about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml14
-rw-r--r--compiler/rustc_ast/src/ast.rs2
-rw-r--r--compiler/rustc_ast/src/ast_traits.rs15
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs18
-rw-r--r--compiler/rustc_ast/src/visit.rs3
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs1
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs1
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/item.rs3
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs19
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs11
-rw-r--r--compiler/rustc_codegen_gcc/src/common.rs13
-rw-r--r--compiler/rustc_codegen_gcc/src/lib.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/common.rs40
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs1
-rw-r--r--compiler/rustc_expand/src/base.rs16
-rw-r--r--compiler/rustc_expand/src/expand.rs38
-rw-r--r--compiler/rustc_expand/src/placeholders.rs24
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_hir/src/target.rs5
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs1
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs6
-rw-r--r--compiler/rustc_parse/src/parser/generics.rs65
-rw-r--r--compiler/rustc_passes/messages.ftl4
-rw-r--r--compiler/rustc_passes/src/check_attr.rs29
-rw-r--r--compiler/rustc_passes/src/errors.rs8
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs8
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs8
-rw-r--r--compiler/rustc_session/src/config.rs64
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--library/core/src/marker/variance.rs12
-rwxr-xr-xsrc/etc/pre-push.sh14
-rw-r--r--src/etc/test-float-parse/src/gen/exhaustive.rs3
-rw-r--r--src/etc/test-float-parse/src/gen/fuzz.rs1
-rw-r--r--src/etc/test-float-parse/src/gen/sparse.rs1
-rw-r--r--src/etc/test-float-parse/src/lib.rs221
-rw-r--r--src/etc/test-float-parse/src/traits.rs2
-rw-r--r--src/etc/test-float-parse/src/ui.rs126
-rw-r--r--src/etc/test-float-parse/src/validate.rs46
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils/mod.rs27
-rw-r--r--src/tools/rustfmt/src/spanned.rs7
-rw-r--r--src/tools/rustfmt/src/types.rs35
-rw-r--r--src/tools/rustfmt/tests/target/cfg_attribute_in_where.rs116
-rw-r--r--tests/assembly/stack-protector/stack-protector-heuristics-effect.rs32
-rw-r--r--tests/run-make/rustc-help/help-v.stdout2
-rw-r--r--tests/run-make/rustc-help/help.stdout2
-rw-r--r--tests/ui/feature-gates/feature-gate-where_clause_attrs.a.stderr883
-rw-r--r--tests/ui/feature-gates/feature-gate-where_clause_attrs.b.stderr883
-rw-r--r--tests/ui/feature-gates/feature-gate-where_clause_attrs.rs162
-rw-r--r--tests/ui/invalid-compile-flags/print-without-arg.stderr2
-rw-r--r--tests/ui/parser/bounds-lifetime-where.rs2
-rw-r--r--tests/ui/parser/bounds-lifetime-where.stderr4
-rw-r--r--tests/ui/parser/issues/misplaced-return-type-where-in-next-line-issue-126311.stderr2
-rw-r--r--tests/ui/parser/ranges-precedence.rs28
-rw-r--r--tests/ui/stats/input-stats.stderr28
-rw-r--r--tests/ui/where-clauses/cfg_attribute.a.stderr288
-rw-r--r--tests/ui/where-clauses/cfg_attribute.b.stderr288
-rw-r--r--tests/ui/where-clauses/cfg_attribute.rs183
-rw-r--r--tests/ui/where-clauses/unsupported_attribute.rs36
-rw-r--r--tests/ui/where-clauses/unsupported_attribute.stderr158
59 files changed, 3606 insertions, 410 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 73467ad267e..0cfbb4e77c4 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -182,20 +182,6 @@ jobs:
       - name: show the current environment
         run: src/ci/scripts/dump-environment.sh
 
-      # Temporary fix to unblock CI
-      # Remove the latest Windows SDK for 32-bit Windows MSVC builds.
-      # See issue https://github.com/rust-lang/rust/issues/137733 for more details.
-      - name: Remove Windows SDK 10.0.26100.0
-        shell: powershell
-        if: ${{ matrix.name == 'i686-msvc-1' || matrix.name == 'i686-msvc-2' || matrix.name == 'dist-i686-msvc' }}
-        run: |
-          $kits = (Get-ItemProperty -path 'HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots').KitsRoot10
-          $sdk_version = "10.0.26100.0"
-
-          foreach ($kind in 'Bin', 'Lib', 'Include') {
-            Remove-Item -Force -Recurse $kits\$kind\$sdk_version -ErrorAction Continue
-          }
-
       - name: run the build
         # Redirect stderr to stdout to avoid reordering the two streams in the GHA logs.
         run: src/ci/scripts/run-build-from-ci.sh 2>&1
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 5c44fda2262..a8d30949ea8 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -417,9 +417,11 @@ impl WhereClause {
 /// A single predicate in a where-clause.
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct WherePredicate {
+    pub attrs: AttrVec,
     pub kind: WherePredicateKind,
     pub id: NodeId,
     pub span: Span,
+    pub is_placeholder: bool,
 }
 
 /// Predicate kind in where-clause.
diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs
index 4a2d9559385..a37c0f92b12 100644
--- a/compiler/rustc_ast/src/ast_traits.rs
+++ b/compiler/rustc_ast/src/ast_traits.rs
@@ -11,7 +11,7 @@ use crate::tokenstream::LazyAttrTokenStream;
 use crate::{
     Arm, AssocItem, AttrItem, AttrKind, AttrVec, Attribute, Block, Crate, Expr, ExprField,
     FieldDef, ForeignItem, GenericParam, Item, NodeId, Param, Pat, PatField, Path, Stmt, StmtKind,
-    Ty, Variant, Visibility,
+    Ty, Variant, Visibility, WherePredicate,
 };
 
 /// A utility trait to reduce boilerplate.
@@ -79,6 +79,7 @@ impl_has_node_id!(
     Stmt,
     Ty,
     Variant,
+    WherePredicate,
 );
 
 impl<T: AstDeref<Target: HasNodeId>> HasNodeId for T {
@@ -127,7 +128,16 @@ macro_rules! impl_has_tokens_none {
 }
 
 impl_has_tokens!(AssocItem, AttrItem, Block, Expr, ForeignItem, Item, Pat, Path, Ty, Visibility);
-impl_has_tokens_none!(Arm, ExprField, FieldDef, GenericParam, Param, PatField, Variant);
+impl_has_tokens_none!(
+    Arm,
+    ExprField,
+    FieldDef,
+    GenericParam,
+    Param,
+    PatField,
+    Variant,
+    WherePredicate
+);
 
 impl<T: AstDeref<Target: HasTokens>> HasTokens for T {
     fn tokens(&self) -> Option<&LazyAttrTokenStream> {
@@ -279,6 +289,7 @@ impl_has_attrs!(
     Param,
     PatField,
     Variant,
+    WherePredicate,
 );
 impl_has_attrs_none!(Attribute, AttrItem, Block, Pat, Path, Ty, Visibility);
 
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 9be364e320b..f14646b5a99 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -338,8 +338,11 @@ pub trait MutVisitor: Sized {
         walk_where_clause(self, where_clause);
     }
 
-    fn visit_where_predicate(&mut self, where_predicate: &mut WherePredicate) {
-        walk_where_predicate(self, where_predicate)
+    fn flat_map_where_predicate(
+        &mut self,
+        where_predicate: WherePredicate,
+    ) -> SmallVec<[WherePredicate; 1]> {
+        walk_flat_map_where_predicate(self, where_predicate)
     }
 
     fn visit_where_predicate_kind(&mut self, kind: &mut WherePredicateKind) {
@@ -1097,15 +1100,20 @@ fn walk_ty_alias_where_clauses<T: MutVisitor>(vis: &mut T, tawcs: &mut TyAliasWh
 
 fn walk_where_clause<T: MutVisitor>(vis: &mut T, wc: &mut WhereClause) {
     let WhereClause { has_where_token: _, predicates, span } = wc;
-    visit_thin_vec(predicates, |predicate| vis.visit_where_predicate(predicate));
+    predicates.flat_map_in_place(|predicate| vis.flat_map_where_predicate(predicate));
     vis.visit_span(span);
 }
 
-pub fn walk_where_predicate<T: MutVisitor>(vis: &mut T, pred: &mut WherePredicate) {
-    let WherePredicate { kind, id, span } = pred;
+pub fn walk_flat_map_where_predicate<T: MutVisitor>(
+    vis: &mut T,
+    mut pred: WherePredicate,
+) -> SmallVec<[WherePredicate; 1]> {
+    let WherePredicate { attrs, kind, id, span, is_placeholder: _ } = &mut pred;
     vis.visit_id(id);
+    visit_attrs(vis, attrs);
     vis.visit_where_predicate_kind(kind);
     vis.visit_span(span);
+    smallvec![pred]
 }
 
 pub fn walk_where_predicate_kind<T: MutVisitor>(vis: &mut T, kind: &mut WherePredicateKind) {
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index 1cb32b56875..37139e664f3 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -833,7 +833,8 @@ pub fn walk_where_predicate<'a, V: Visitor<'a>>(
     visitor: &mut V,
     predicate: &'a WherePredicate,
 ) -> V::Result {
-    let WherePredicate { kind, id: _, span: _ } = predicate;
+    let WherePredicate { attrs, kind, id: _, span: _, is_placeholder: _ } = predicate;
+    walk_list!(visitor, visit_attribute, attrs);
     visitor.visit_where_predicate_kind(kind)
 }
 
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 15802101f71..5e89321e6ec 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1728,6 +1728,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
         let hir_id = self.lower_node_id(pred.id);
         let span = self.lower_span(pred.span);
+        self.lower_attrs(hir_id, &pred.attrs, span);
         let kind = self.arena.alloc(match &pred.kind {
             WherePredicateKind::BoundPredicate(WhereBoundPredicate {
                 bound_generic_params,
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 0f80e49320e..de11fe770c5 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -503,6 +503,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
     gate_all!(unsafe_binders, "unsafe binder types are experimental");
     gate_all!(contracts, "contracts are incomplete");
     gate_all!(contracts_internals, "contract internal machinery is for internal use only");
+    gate_all!(where_clause_attrs, "attributes in `where` clause are unstable");
 
     if !visitor.features.never_patterns() {
         if let Some(spans) = spans.get(&sym::never_patterns) {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
index c10b5ad34e1..ced0cbd2fef 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
@@ -735,7 +735,8 @@ impl<'a> State<'a> {
     }
 
     pub fn print_where_predicate(&mut self, predicate: &ast::WherePredicate) {
-        let ast::WherePredicate { kind, id: _, span: _ } = predicate;
+        let ast::WherePredicate { attrs, kind, id: _, span: _, is_placeholder: _ } = predicate;
+        self.print_outer_attributes(attrs);
         match kind {
             ast::WherePredicateKind::BoundPredicate(where_bound_predicate) => {
                 self.print_where_bound_predicate(where_bound_predicate);
diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
index 5aed9f76f14..46b79e09780 100644
--- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
@@ -300,13 +300,16 @@ pub(crate) fn expand_deriving_coerce_pointee(
                 to_ty: &s_ty,
                 rewritten: false,
             };
-            let mut predicate = ast::WherePredicate {
-                kind: ast::WherePredicateKind::BoundPredicate(bound.clone()),
-                span: predicate.span,
-                id: ast::DUMMY_NODE_ID,
-            };
-            substitution.visit_where_predicate(&mut predicate);
+            let mut kind = ast::WherePredicateKind::BoundPredicate(bound.clone());
+            substitution.visit_where_predicate_kind(&mut kind);
             if substitution.rewritten {
+                let predicate = ast::WherePredicate {
+                    attrs: predicate.attrs.clone(),
+                    kind,
+                    span: predicate.span,
+                    id: ast::DUMMY_NODE_ID,
+                    is_placeholder: false,
+                };
                 impl_generics.where_clause.predicates.push(predicate);
             }
         }
@@ -388,8 +391,8 @@ impl<'a> ast::mut_visit::MutVisitor for TypeSubstitution<'a> {
         }
     }
 
-    fn visit_where_predicate(&mut self, where_predicate: &mut ast::WherePredicate) {
-        match &mut where_predicate.kind {
+    fn visit_where_predicate_kind(&mut self, kind: &mut ast::WherePredicateKind) {
+        match kind {
             rustc_ast::WherePredicateKind::BoundPredicate(bound) => {
                 bound
                     .bound_generic_params
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index 6b59ac25827..5402b5a1ae9 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -687,9 +687,11 @@ impl<'a> TraitDef<'a> {
         // and similarly for where clauses
         where_clause.predicates.extend(generics.where_clause.predicates.iter().map(|clause| {
             ast::WherePredicate {
+                attrs: clause.attrs.clone(),
                 kind: clause.kind.clone(),
                 id: ast::DUMMY_NODE_ID,
                 span: clause.span.with_ctxt(ctxt),
+                is_placeholder: false,
             }
         }));
 
@@ -744,8 +746,13 @@ impl<'a> TraitDef<'a> {
                         };
 
                         let kind = ast::WherePredicateKind::BoundPredicate(predicate);
-                        let predicate =
-                            ast::WherePredicate { kind, id: ast::DUMMY_NODE_ID, span: self.span };
+                        let predicate = ast::WherePredicate {
+                            attrs: ThinVec::new(),
+                            kind,
+                            id: ast::DUMMY_NODE_ID,
+                            span: self.span,
+                            is_placeholder: false,
+                        };
                         where_clause.predicates.push(predicate);
                     }
                 }
diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs
index 20a3482aaa2..ce1a2008864 100644
--- a/compiler/rustc_codegen_gcc/src/common.rs
+++ b/compiler/rustc_codegen_gcc/src/common.rs
@@ -146,13 +146,12 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
     }
 
     fn const_str(&self, s: &str) -> (RValue<'gcc>, RValue<'gcc>) {
-        let str_global = *self
-            .const_str_cache
-            .borrow_mut()
-            .raw_entry_mut()
-            .from_key(s)
-            .or_insert_with(|| (s.to_owned(), self.global_string(s)))
-            .1;
+        let mut const_str_cache = self.const_str_cache.borrow_mut();
+        let str_global = const_str_cache.get(s).copied().unwrap_or_else(|| {
+            let g = self.global_string(s);
+            const_str_cache.insert(s.to_owned(), g);
+            g
+        });
         let len = s.len();
         let cs = self.const_ptrcast(
             str_global.get_address(None),
diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs
index 9d91aab72ab..f090597f953 100644
--- a/compiler/rustc_codegen_gcc/src/lib.rs
+++ b/compiler/rustc_codegen_gcc/src/lib.rs
@@ -16,7 +16,7 @@
 #![allow(internal_features)]
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
-#![feature(rustc_private, decl_macro, never_type, trusted_len, hash_raw_entry, let_chains)]
+#![feature(rustc_private, decl_macro, never_type, trusted_len, let_chains)]
 #![allow(broken_intra_doc_links)]
 #![recursion_limit = "256"]
 #![warn(rust_2018_idioms)]
diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs
index 0621b893e75..6eaecfa87a9 100644
--- a/compiler/rustc_codegen_llvm/src/common.rs
+++ b/compiler/rustc_codegen_llvm/src/common.rs
@@ -209,28 +209,24 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
     }
 
     fn const_str(&self, s: &str) -> (&'ll Value, &'ll Value) {
-        let str_global = *self
-            .const_str_cache
-            .borrow_mut()
-            .raw_entry_mut()
-            .from_key(s)
-            .or_insert_with(|| {
-                let sc = self.const_bytes(s.as_bytes());
-                let sym = self.generate_local_symbol_name("str");
-                let g = self.define_global(&sym, self.val_ty(sc)).unwrap_or_else(|| {
-                    bug!("symbol `{}` is already defined", sym);
-                });
-                llvm::set_initializer(g, sc);
-                unsafe {
-                    llvm::LLVMSetGlobalConstant(g, True);
-                    llvm::LLVMSetUnnamedAddress(g, llvm::UnnamedAddr::Global);
-                }
-                llvm::set_linkage(g, llvm::Linkage::InternalLinkage);
-                // Cast to default address space if globals are in a different addrspace
-                let g = self.const_pointercast(g, self.type_ptr());
-                (s.to_owned(), g)
-            })
-            .1;
+        let mut const_str_cache = self.const_str_cache.borrow_mut();
+        let str_global = const_str_cache.get(s).copied().unwrap_or_else(|| {
+            let sc = self.const_bytes(s.as_bytes());
+            let sym = self.generate_local_symbol_name("str");
+            let g = self.define_global(&sym, self.val_ty(sc)).unwrap_or_else(|| {
+                bug!("symbol `{}` is already defined", sym);
+            });
+            llvm::set_initializer(g, sc);
+            unsafe {
+                llvm::LLVMSetGlobalConstant(g, True);
+                llvm::LLVMSetUnnamedAddress(g, llvm::UnnamedAddr::Global);
+            }
+            llvm::set_linkage(g, llvm::Linkage::InternalLinkage);
+            // Cast to default address space if globals are in a different addrspace
+            let g = self.const_pointercast(g, self.type_ptr());
+            const_str_cache.insert(s.to_owned(), g);
+            g
+        });
         let len = s.len();
         (str_global, self.const_usize(len as u64))
     }
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index c88372db491..8f72307eeba 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -12,7 +12,6 @@
 #![feature(exact_size_is_empty)]
 #![feature(extern_types)]
 #![feature(file_buffered)]
-#![feature(hash_raw_entry)]
 #![feature(if_let_guard)]
 #![feature(impl_trait_in_assoc_type)]
 #![feature(iter_intersperse)]
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 4a250145308..86b12f6be4e 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -53,6 +53,7 @@ pub enum Annotatable {
     Param(ast::Param),
     FieldDef(ast::FieldDef),
     Variant(ast::Variant),
+    WherePredicate(ast::WherePredicate),
     Crate(ast::Crate),
 }
 
@@ -71,6 +72,7 @@ impl Annotatable {
             Annotatable::Param(p) => p.span,
             Annotatable::FieldDef(sf) => sf.span,
             Annotatable::Variant(v) => v.span,
+            Annotatable::WherePredicate(wp) => wp.span,
             Annotatable::Crate(c) => c.spans.inner_span,
         }
     }
@@ -89,6 +91,7 @@ impl Annotatable {
             Annotatable::Param(p) => p.visit_attrs(f),
             Annotatable::FieldDef(sf) => sf.visit_attrs(f),
             Annotatable::Variant(v) => v.visit_attrs(f),
+            Annotatable::WherePredicate(wp) => wp.visit_attrs(f),
             Annotatable::Crate(c) => c.visit_attrs(f),
         }
     }
@@ -107,6 +110,7 @@ impl Annotatable {
             Annotatable::Param(p) => visitor.visit_param(p),
             Annotatable::FieldDef(sf) => visitor.visit_field_def(sf),
             Annotatable::Variant(v) => visitor.visit_variant(v),
+            Annotatable::WherePredicate(wp) => visitor.visit_where_predicate(wp),
             Annotatable::Crate(c) => visitor.visit_crate(c),
         }
     }
@@ -128,6 +132,7 @@ impl Annotatable {
             | Annotatable::Param(..)
             | Annotatable::FieldDef(..)
             | Annotatable::Variant(..)
+            | Annotatable::WherePredicate(..)
             | Annotatable::Crate(..) => panic!("unexpected annotatable"),
         }
     }
@@ -223,6 +228,13 @@ impl Annotatable {
         }
     }
 
+    pub fn expect_where_predicate(self) -> ast::WherePredicate {
+        match self {
+            Annotatable::WherePredicate(wp) => wp,
+            _ => panic!("expected where predicate"),
+        }
+    }
+
     pub fn expect_crate(self) -> ast::Crate {
         match self {
             Annotatable::Crate(krate) => krate,
@@ -446,6 +458,10 @@ pub trait MacResult {
         None
     }
 
+    fn make_where_predicates(self: Box<Self>) -> Option<SmallVec<[ast::WherePredicate; 1]>> {
+        None
+    }
+
     fn make_crate(self: Box<Self>) -> Option<ast::Crate> {
         // Fn-like macros cannot produce a crate.
         unreachable!()
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index e3f31ebeca3..c523bcece72 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -227,6 +227,12 @@ ast_fragments! {
     Variants(SmallVec<[ast::Variant; 1]>) {
         "variant"; many fn flat_map_variant; fn visit_variant(); fn make_variants;
     }
+    WherePredicates(SmallVec<[ast::WherePredicate; 1]>) {
+        "where predicate";
+        many fn flat_map_where_predicate;
+        fn visit_where_predicate();
+        fn make_where_predicates;
+     }
     Crate(ast::Crate) { "crate"; one fn visit_crate; fn visit_crate; fn make_crate; }
 }
 
@@ -259,7 +265,8 @@ impl AstFragmentKind {
             | AstFragmentKind::GenericParams
             | AstFragmentKind::Params
             | AstFragmentKind::FieldDefs
-            | AstFragmentKind::Variants => SupportsMacroExpansion::No,
+            | AstFragmentKind::Variants
+            | AstFragmentKind::WherePredicates => SupportsMacroExpansion::No,
         }
     }
 
@@ -290,6 +297,9 @@ impl AstFragmentKind {
             AstFragmentKind::Variants => {
                 AstFragment::Variants(items.map(Annotatable::expect_variant).collect())
             }
+            AstFragmentKind::WherePredicates => AstFragment::WherePredicates(
+                items.map(Annotatable::expect_where_predicate).collect(),
+            ),
             AstFragmentKind::Items => {
                 AstFragment::Items(items.map(Annotatable::expect_item).collect())
             }
@@ -865,7 +875,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             | Annotatable::GenericParam(..)
             | Annotatable::Param(..)
             | Annotatable::FieldDef(..)
-            | Annotatable::Variant(..) => panic!("unexpected annotatable"),
+            | Annotatable::Variant(..)
+            | Annotatable::WherePredicate(..) => panic!("unexpected annotatable"),
         };
         if self.cx.ecfg.features.proc_macro_hygiene() {
             return;
@@ -1002,7 +1013,8 @@ pub fn parse_ast_fragment<'a>(
         | AstFragmentKind::GenericParams
         | AstFragmentKind::Params
         | AstFragmentKind::FieldDefs
-        | AstFragmentKind::Variants => panic!("unexpected AST fragment kind"),
+        | AstFragmentKind::Variants
+        | AstFragmentKind::WherePredicates => panic!("unexpected AST fragment kind"),
     })
 }
 
@@ -1414,6 +1426,19 @@ impl InvocationCollectorNode for ast::Variant {
     }
 }
 
+impl InvocationCollectorNode for ast::WherePredicate {
+    const KIND: AstFragmentKind = AstFragmentKind::WherePredicates;
+    fn to_annotatable(self) -> Annotatable {
+        Annotatable::WherePredicate(self)
+    }
+    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
+        fragment.make_where_predicates()
+    }
+    fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
+        walk_flat_map_where_predicate(visitor, self)
+    }
+}
+
 impl InvocationCollectorNode for ast::FieldDef {
     const KIND: AstFragmentKind = AstFragmentKind::FieldDefs;
     fn to_annotatable(self) -> Annotatable {
@@ -2116,6 +2141,13 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
         self.flat_map_node(node)
     }
 
+    fn flat_map_where_predicate(
+        &mut self,
+        node: ast::WherePredicate,
+    ) -> SmallVec<[ast::WherePredicate; 1]> {
+        self.flat_map_node(node)
+    }
+
     fn flat_map_field_def(&mut self, node: ast::FieldDef) -> SmallVec<[ast::FieldDef; 1]> {
         self.flat_map_node(node)
     }
diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs
index e969f2d4fb5..3a470924c7f 100644
--- a/compiler/rustc_expand/src/placeholders.rs
+++ b/compiler/rustc_expand/src/placeholders.rs
@@ -188,6 +188,19 @@ pub(crate) fn placeholder(
             vis,
             is_placeholder: true,
         }]),
+        AstFragmentKind::WherePredicates => {
+            AstFragment::WherePredicates(smallvec![ast::WherePredicate {
+                attrs: Default::default(),
+                id,
+                span,
+                kind: ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate {
+                    bound_generic_params: Default::default(),
+                    bounded_ty: ty(),
+                    bounds: Default::default(),
+                }),
+                is_placeholder: true,
+            }])
+        }
     }
 }
 
@@ -267,6 +280,17 @@ impl MutVisitor for PlaceholderExpander {
         }
     }
 
+    fn flat_map_where_predicate(
+        &mut self,
+        predicate: ast::WherePredicate,
+    ) -> SmallVec<[ast::WherePredicate; 1]> {
+        if predicate.is_placeholder {
+            self.remove(predicate.id).make_where_predicates()
+        } else {
+            walk_flat_map_where_predicate(self, predicate)
+        }
+    }
+
     fn flat_map_item(&mut self, item: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
         match item.kind {
             ast::ItemKind::MacCall(_) => self.remove(item.id).make_items(),
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 0acd3b0f800..10b50396bc9 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -661,6 +661,8 @@ declare_features! (
     (unstable, unsized_tuple_coercion, "1.20.0", Some(42877)),
     /// Allows using the `#[used(linker)]` (or `#[used(compiler)]`) attribute.
     (unstable, used_with_arg, "1.60.0", Some(93798)),
+    /// Allows use of attributes in `where` clauses.
+    (unstable, where_clause_attrs, "CURRENT_RUSTC_VERSION", Some(115590)),
     /// Allows use of x86 `AMX` target-feature attributes and intrinsics
     (unstable, x86_amx_intrinsics, "1.81.0", Some(126622)),
     /// Allows use of the `xop` target-feature
diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs
index 70e95a84e68..601898023fc 100644
--- a/compiler/rustc_hir/src/target.rs
+++ b/compiler/rustc_hir/src/target.rs
@@ -56,6 +56,7 @@ pub enum Target {
     Param,
     PatField,
     ExprField,
+    WherePredicate,
 }
 
 impl Display for Target {
@@ -96,7 +97,8 @@ impl Target {
             | Target::MacroDef
             | Target::Param
             | Target::PatField
-            | Target::ExprField => false,
+            | Target::ExprField
+            | Target::WherePredicate => false,
         }
     }
 
@@ -217,6 +219,7 @@ impl Target {
             Target::Param => "function param",
             Target::PatField => "pattern field",
             Target::ExprField => "struct field",
+            Target::WherePredicate => "where predicate",
         }
     }
 }
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index e06398cf3c4..22edc18d71c 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -2386,6 +2386,7 @@ impl<'a> State<'a> {
     }
 
     fn print_where_predicate(&mut self, predicate: &hir::WherePredicate<'_>) {
+        self.print_attrs_as_outer(self.attrs(predicate.hir_id));
         match *predicate.kind {
             hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
                 bound_generic_params,
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index ef29ac2719d..d93f8c4b103 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -567,7 +567,11 @@ impl<'a> Parser<'a> {
     fn parse_expr_prefix_common(&mut self, lo: Span) -> PResult<'a, (Span, P<Expr>)> {
         self.bump();
         let attrs = self.parse_outer_attributes()?;
-        let expr = self.parse_expr_prefix(attrs)?;
+        let expr = if self.token.is_range_separator() {
+            self.parse_expr_prefix_range(attrs)
+        } else {
+            self.parse_expr_prefix(attrs)
+        }?;
         let span = self.interpolated_or_expr_span(&expr);
         Ok((lo.to(span), expr))
     }
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs
index 11f0e579de5..c3f71dd8b30 100644
--- a/compiler/rustc_parse/src/parser/generics.rs
+++ b/compiler/rustc_parse/src/parser/generics.rs
@@ -367,34 +367,47 @@ impl<'a> Parser<'a> {
 
         loop {
             let where_sp = where_lo.to(self.prev_token.span);
+            let attrs = self.parse_outer_attributes()?;
             let pred_lo = self.token.span;
-            let kind = if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
-                let lifetime = self.expect_lifetime();
-                // Bounds starting with a colon are mandatory, but possibly empty.
-                self.expect(exp!(Colon))?;
-                let bounds = self.parse_lt_param_bounds();
-                ast::WherePredicateKind::RegionPredicate(ast::WhereRegionPredicate {
-                    lifetime,
-                    bounds,
-                })
-            } else if self.check_type() {
-                match self.parse_ty_where_predicate_kind_or_recover_tuple_struct_body(
-                    struct_, pred_lo, where_sp,
-                )? {
-                    PredicateKindOrStructBody::PredicateKind(kind) => kind,
-                    PredicateKindOrStructBody::StructBody(body) => {
-                        tuple_struct_body = Some(body);
-                        break;
-                    }
+            let predicate = self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
+                for attr in &attrs {
+                    self.psess.gated_spans.gate(sym::where_clause_attrs, attr.span);
                 }
-            } else {
-                break;
-            };
-            where_clause.predicates.push(ast::WherePredicate {
-                kind,
-                id: DUMMY_NODE_ID,
-                span: pred_lo.to(self.prev_token.span),
-            });
+                let kind = if this.check_lifetime() && this.look_ahead(1, |t| !t.is_like_plus()) {
+                    let lifetime = this.expect_lifetime();
+                    // Bounds starting with a colon are mandatory, but possibly empty.
+                    this.expect(exp!(Colon))?;
+                    let bounds = this.parse_lt_param_bounds();
+                    Some(ast::WherePredicateKind::RegionPredicate(ast::WhereRegionPredicate {
+                        lifetime,
+                        bounds,
+                    }))
+                } else if this.check_type() {
+                    match this.parse_ty_where_predicate_kind_or_recover_tuple_struct_body(
+                        struct_, pred_lo, where_sp,
+                    )? {
+                        PredicateKindOrStructBody::PredicateKind(kind) => Some(kind),
+                        PredicateKindOrStructBody::StructBody(body) => {
+                            tuple_struct_body = Some(body);
+                            None
+                        }
+                    }
+                } else {
+                    None
+                };
+                let predicate = kind.map(|kind| ast::WherePredicate {
+                    attrs,
+                    kind,
+                    id: DUMMY_NODE_ID,
+                    span: pred_lo.to(this.prev_token.span),
+                    is_placeholder: false,
+                });
+                Ok((predicate, Trailing::No, UsePreAttrPos::No))
+            })?;
+            match predicate {
+                Some(predicate) => where_clause.predicates.push(predicate),
+                None => break,
+            }
 
             let prev_token = self.prev_token.span;
             let ate_comma = self.eat(exp!(Comma));
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index b65430c3480..ed498d9d344 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -779,6 +779,10 @@ passes_unstable_attr_for_already_stable_feature =
     .item = the stability attribute annotates this item
     .help = consider removing the attribute
 
+passes_unsupported_attributes_in_where =
+    most attributes are not supported in `where` clauses
+    .help = only `#[cfg]` and `#[cfg_attr]` are supported
+
 passes_unused =
     unused attribute
     .suggestion = remove this attribute
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 5ada289cc20..d6c0edf5ae7 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -919,7 +919,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             | Target::Arm
             | Target::ForeignMod
             | Target::Closure
-            | Target::Impl => Some(target.name()),
+            | Target::Impl
+            | Target::WherePredicate => Some(target.name()),
             Target::ExternCrate
             | Target::Use
             | Target::Static
@@ -2614,6 +2615,32 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
         intravisit::walk_item(self, item)
     }
 
+    fn visit_where_predicate(&mut self, where_predicate: &'tcx hir::WherePredicate<'tcx>) {
+        // FIXME(where_clause_attrs): Currently, as the following check shows,
+        // only `#[cfg]` and `#[cfg_attr]` are allowed, but it should be removed
+        // if we allow more attributes (e.g., tool attributes and `allow/deny/warn`)
+        // in where clauses. After that, only `self.check_attributes` should be enough.
+        const ATTRS_ALLOWED: &[Symbol] = &[sym::cfg, sym::cfg_attr];
+        let spans = self
+            .tcx
+            .hir()
+            .attrs(where_predicate.hir_id)
+            .iter()
+            .filter(|attr| !ATTRS_ALLOWED.iter().any(|&sym| attr.has_name(sym)))
+            .map(|attr| attr.span())
+            .collect::<Vec<_>>();
+        if !spans.is_empty() {
+            self.tcx.dcx().emit_err(errors::UnsupportedAttributesInWhere { span: spans.into() });
+        }
+        self.check_attributes(
+            where_predicate.hir_id,
+            where_predicate.span,
+            Target::WherePredicate,
+            None,
+        );
+        intravisit::walk_where_predicate(self, where_predicate)
+    }
+
     fn visit_generic_param(&mut self, generic_param: &'tcx hir::GenericParam<'tcx>) {
         let target = Target::from_generic_param(generic_param);
         self.check_attributes(generic_param.hir_id, generic_param.span, target, None);
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 9bb9b2353dc..b8359c27e53 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -1909,3 +1909,11 @@ pub(crate) struct RustcConstStableIndirectPairing {
     #[primary_span]
     pub span: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(passes_unsupported_attributes_in_where)]
+#[help]
+pub(crate) struct UnsupportedAttributesInWhere {
+    #[primary_span]
+    pub span: MultiSpan,
+}
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 87f7eda391d..42fe01b1c84 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -1529,6 +1529,14 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
         visit::walk_variant(self, variant);
     }
 
+    fn visit_where_predicate(&mut self, p: &'a ast::WherePredicate) {
+        if p.is_placeholder {
+            self.visit_invoc(p.id);
+        } else {
+            visit::walk_where_predicate(self, p);
+        }
+    }
+
     fn visit_crate(&mut self, krate: &'a ast::Crate) {
         if krate.is_placeholder {
             self.visit_invoc_in_module(krate.id);
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index 9d78c71b76a..95d637b6b22 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -285,6 +285,14 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
         });
     }
 
+    fn visit_where_predicate(&mut self, pred: &'a WherePredicate) {
+        if pred.is_placeholder {
+            self.visit_macro_invoc(pred.id)
+        } else {
+            visit::walk_where_predicate(self, pred)
+        }
+    }
+
     fn visit_variant_data(&mut self, data: &'a VariantData) {
         // The assumption here is that non-`cfg` macro expansion cannot change field indices.
         // It currently holds because only inert attributes are accepted on fields,
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 7586c5766b5..2f67660a46b 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -42,6 +42,32 @@ mod cfg;
 mod native_libs;
 pub mod sigpipe;
 
+pub const PRINT_KINDS: &[(&str, PrintKind)] = &[
+    // tidy-alphabetical-start
+    ("all-target-specs-json", PrintKind::AllTargetSpecs),
+    ("calling-conventions", PrintKind::CallingConventions),
+    ("cfg", PrintKind::Cfg),
+    ("check-cfg", PrintKind::CheckCfg),
+    ("code-models", PrintKind::CodeModels),
+    ("crate-name", PrintKind::CrateName),
+    ("deployment-target", PrintKind::DeploymentTarget),
+    ("file-names", PrintKind::FileNames),
+    ("host-tuple", PrintKind::HostTuple),
+    ("link-args", PrintKind::LinkArgs),
+    ("native-static-libs", PrintKind::NativeStaticLibs),
+    ("relocation-models", PrintKind::RelocationModels),
+    ("split-debuginfo", PrintKind::SplitDebuginfo),
+    ("stack-protector-strategies", PrintKind::StackProtectorStrategies),
+    ("sysroot", PrintKind::Sysroot),
+    ("target-cpus", PrintKind::TargetCPUs),
+    ("target-features", PrintKind::TargetFeatures),
+    ("target-libdir", PrintKind::TargetLibdir),
+    ("target-list", PrintKind::TargetList),
+    ("target-spec-json", PrintKind::TargetSpec),
+    ("tls-models", PrintKind::TlsModels),
+    // tidy-alphabetical-end
+];
+
 /// The different settings that the `-C strip` flag can have.
 #[derive(Clone, Copy, PartialEq, Hash, Debug)]
 pub enum Strip {
@@ -1508,6 +1534,13 @@ The default is {DEFAULT_EDITION} and the latest stable edition is {LATEST_STABLE
     )
 });
 
+static PRINT_KINDS_STRING: LazyLock<String> = LazyLock::new(|| {
+    format!(
+        "[{}]",
+        PRINT_KINDS.iter().map(|(name, _)| format!("{name}")).collect::<Vec<_>>().join("|")
+    )
+});
+
 /// Returns all rustc command line options, including metadata for
 /// each option, such as whether the option is stable.
 pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
@@ -1568,10 +1601,7 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
             "",
             "print",
             "Compiler information to print on stdout",
-            "[crate-name|file-names|sysroot|target-libdir|cfg|check-cfg|calling-conventions|\
-             target-list|target-cpus|target-features|relocation-models|code-models|\
-             tls-models|target-spec-json|all-target-specs-json|native-static-libs|\
-             stack-protector-strategies|link-args|deployment-target]",
+            &PRINT_KINDS_STRING,
         ),
         opt(Stable, FlagMulti, "g", "", "Equivalent to -C debuginfo=2", ""),
         opt(Stable, FlagMulti, "O", "", "Equivalent to -C opt-level=3", ""),
@@ -1999,32 +2029,6 @@ fn collect_print_requests(
         cg.target_feature = String::new();
     }
 
-    const PRINT_KINDS: &[(&str, PrintKind)] = &[
-        // tidy-alphabetical-start
-        ("all-target-specs-json", PrintKind::AllTargetSpecs),
-        ("calling-conventions", PrintKind::CallingConventions),
-        ("cfg", PrintKind::Cfg),
-        ("check-cfg", PrintKind::CheckCfg),
-        ("code-models", PrintKind::CodeModels),
-        ("crate-name", PrintKind::CrateName),
-        ("deployment-target", PrintKind::DeploymentTarget),
-        ("file-names", PrintKind::FileNames),
-        ("host-tuple", PrintKind::HostTuple),
-        ("link-args", PrintKind::LinkArgs),
-        ("native-static-libs", PrintKind::NativeStaticLibs),
-        ("relocation-models", PrintKind::RelocationModels),
-        ("split-debuginfo", PrintKind::SplitDebuginfo),
-        ("stack-protector-strategies", PrintKind::StackProtectorStrategies),
-        ("sysroot", PrintKind::Sysroot),
-        ("target-cpus", PrintKind::TargetCPUs),
-        ("target-features", PrintKind::TargetFeatures),
-        ("target-libdir", PrintKind::TargetLibdir),
-        ("target-list", PrintKind::TargetList),
-        ("target-spec-json", PrintKind::TargetSpec),
-        ("tls-models", PrintKind::TlsModels),
-        // tidy-alphabetical-end
-    ];
-
     // We disallow reusing the same path in multiple prints, such as `--print
     // cfg=output.txt --print link-args=output.txt`, because outputs are printed
     // by disparate pieces of the compiler, and keeping track of which files
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 2a709b07255..3524709eebc 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -2234,6 +2234,7 @@ symbols! {
         wasm_abi,
         wasm_import_module,
         wasm_target_feature,
+        where_clause_attrs,
         while_let,
         windows,
         windows_subsystem,
diff --git a/library/core/src/marker/variance.rs b/library/core/src/marker/variance.rs
index 23334e6575d..235f8a3bb79 100644
--- a/library/core/src/marker/variance.rs
+++ b/library/core/src/marker/variance.rs
@@ -136,6 +136,8 @@ phantom_lifetime! {
     /// For all `'a`, the following are guaranteed:
     /// * `size_of::<PhantomCovariantLifetime<'a>>() == 0`
     /// * `align_of::<PhantomCovariantLifetime<'a>>() == 1`
+    #[rustc_pub_transparent]
+    #[repr(transparent)]
     pub struct PhantomCovariantLifetime<'a>(PhantomCovariant<&'a ()>);
     /// Zero-sized type used to mark a lifetime as contravariant.
     ///
@@ -149,6 +151,8 @@ phantom_lifetime! {
     /// For all `'a`, the following are guaranteed:
     /// * `size_of::<PhantomContravariantLifetime<'a>>() == 0`
     /// * `align_of::<PhantomContravariantLifetime<'a>>() == 1`
+    #[rustc_pub_transparent]
+    #[repr(transparent)]
     pub struct PhantomContravariantLifetime<'a>(PhantomContravariant<&'a ()>);
     /// Zero-sized type used to mark a lifetime as invariant.
     ///
@@ -162,6 +166,8 @@ phantom_lifetime! {
     /// For all `'a`, the following are guaranteed:
     /// * `size_of::<PhantomInvariantLifetime<'a>>() == 0`
     /// * `align_of::<PhantomInvariantLifetime<'a>>() == 1`
+    #[rustc_pub_transparent]
+    #[repr(transparent)]
     pub struct PhantomInvariantLifetime<'a>(PhantomInvariant<&'a ()>);
 }
 
@@ -179,6 +185,8 @@ phantom_type! {
     /// For all `T`, the following are guaranteed:
     /// * `size_of::<PhantomCovariant<T>>() == 0`
     /// * `align_of::<PhantomCovariant<T>>() == 1`
+    #[rustc_pub_transparent]
+    #[repr(transparent)]
     pub struct PhantomCovariant<T>(PhantomData<fn() -> T>);
     /// Zero-sized type used to mark a type parameter as contravariant.
     ///
@@ -193,6 +201,8 @@ phantom_type! {
     /// For all `T`, the following are guaranteed:
     /// * `size_of::<PhantomContravariant<T>>() == 0`
     /// * `align_of::<PhantomContravariant<T>>() == 1`
+    #[rustc_pub_transparent]
+    #[repr(transparent)]
     pub struct PhantomContravariant<T>(PhantomData<fn(T)>);
     /// Zero-sized type used to mark a type parameter as invariant.
     ///
@@ -206,6 +216,8 @@ phantom_type! {
     /// For all `T`, the following are guaranteed:
     /// * `size_of::<PhantomInvariant<T>>() == 0`
     /// * `align_of::<PhantomInvariant<T>>() == 1`
+    #[rustc_pub_transparent]
+    #[repr(transparent)]
     pub struct PhantomInvariant<T>(PhantomData<fn(T) -> T>);
 }
 
diff --git a/src/etc/pre-push.sh b/src/etc/pre-push.sh
index 6f86c7ab8a4..7bacc943f25 100755
--- a/src/etc/pre-push.sh
+++ b/src/etc/pre-push.sh
@@ -7,6 +7,20 @@
 
 set -Euo pipefail
 
+# Check if the push is doing anything other than deleting remote branches
+SKIP=true
+while read LOCAL_REF LOCAL_SHA REMOTE_REF REMOTE_SHA; do
+    if [[ "$LOCAL_REF" != "(delete)" || \
+          "$LOCAL_SHA" != "0000000000000000000000000000000000000000" ]]; then
+        SKIP=false
+    fi
+done
+
+if $SKIP; then
+    echo "Skipping tidy check for branch deletion"
+    exit 0
+fi
+
 ROOT_DIR="$(git rev-parse --show-toplevel)"
 
 echo "Running pre-push script $ROOT_DIR/x test tidy"
diff --git a/src/etc/test-float-parse/src/gen/exhaustive.rs b/src/etc/test-float-parse/src/gen/exhaustive.rs
index 5d4b6df8e59..01458fb0b60 100644
--- a/src/etc/test-float-parse/src/gen/exhaustive.rs
+++ b/src/etc/test-float-parse/src/gen/exhaustive.rs
@@ -13,13 +13,12 @@ impl<F: Float> Generator<F> for Exhaustive<F>
 where
     RangeInclusive<F::Int>: Iterator<Item = F::Int>,
 {
-    const NAME: &'static str = "exhaustive";
     const SHORT_NAME: &'static str = "exhaustive";
 
     type WriteCtx = F;
 
     fn total_tests() -> u64 {
-        F::Int::MAX.try_into().unwrap_or(u64::MAX)
+        1u64.checked_shl(F::Int::BITS).expect("More than u64::MAX tests")
     }
 
     fn new() -> Self {
diff --git a/src/etc/test-float-parse/src/gen/fuzz.rs b/src/etc/test-float-parse/src/gen/fuzz.rs
index 0c63e8aae26..7fc999d1671 100644
--- a/src/etc/test-float-parse/src/gen/fuzz.rs
+++ b/src/etc/test-float-parse/src/gen/fuzz.rs
@@ -49,7 +49,6 @@ impl<F: Float> Generator<F> for Fuzz<F>
 where
     Standard: Distribution<<F as Float>::Int>,
 {
-    const NAME: &'static str = "fuzz";
     const SHORT_NAME: &'static str = "fuzz";
 
     type WriteCtx = F;
diff --git a/src/etc/test-float-parse/src/gen/sparse.rs b/src/etc/test-float-parse/src/gen/sparse.rs
index 389b71056a3..72b65d4ce7f 100644
--- a/src/etc/test-float-parse/src/gen/sparse.rs
+++ b/src/etc/test-float-parse/src/gen/sparse.rs
@@ -35,7 +35,6 @@ impl<F: Float> Generator<F> for FewOnesInt<F>
 where
     <F::Int as TryFrom<u128>>::Error: std::fmt::Debug,
 {
-    const NAME: &'static str = "few ones int";
     const SHORT_NAME: &'static str = "few ones int";
 
     type WriteCtx = F::Int;
diff --git a/src/etc/test-float-parse/src/lib.rs b/src/etc/test-float-parse/src/lib.rs
index 3c71b0dc32e..def66398d9f 100644
--- a/src/etc/test-float-parse/src/lib.rs
+++ b/src/etc/test-float-parse/src/lib.rs
@@ -2,19 +2,19 @@ mod traits;
 mod ui;
 mod validate;
 
-use std::any::{TypeId, type_name};
+use std::any::type_name;
 use std::cmp::min;
 use std::ops::RangeInclusive;
 use std::process::ExitCode;
+use std::sync::OnceLock;
 use std::sync::atomic::{AtomicU64, Ordering};
-use std::sync::{OnceLock, mpsc};
 use std::{fmt, time};
 
-use indicatif::{MultiProgress, ProgressBar};
 use rand::distributions::{Distribution, Standard};
 use rayon::prelude::*;
 use time::{Duration, Instant};
 use traits::{Float, Generator, Int};
+use validate::CheckError;
 
 /// Test generators.
 mod gen {
@@ -43,7 +43,7 @@ const HUGE_TEST_CUTOFF: u64 = 5_000_000;
 /// Seed for tests that use a deterministic RNG.
 const SEED: [u8; 32] = *b"3.141592653589793238462643383279";
 
-/// Global configuration
+/// Global configuration.
 #[derive(Debug)]
 pub struct Config {
     pub timeout: Duration,
@@ -104,9 +104,9 @@ pub fn run(cfg: Config, include: &[String], exclude: &[String]) -> ExitCode {
         println!("Skipping test '{exc}'");
     }
 
-    println!("launching");
+    println!("Launching all");
     let elapsed = launch_tests(&mut tests, &cfg);
-    ui::finish(&tests, elapsed, &cfg)
+    ui::finish_all(&tests, elapsed, &cfg)
 }
 
 /// Enumerate tests to run but don't actually run them.
@@ -160,18 +160,18 @@ where
 #[derive(Debug)]
 pub struct TestInfo {
     pub name: String,
-    /// Tests are identified by the type ID of `(F, G)` (tuple of the float and generator type).
-    /// This gives an easy way to associate messages with tests.
-    id: TypeId,
     float_name: &'static str,
+    float_bits: u32,
     gen_name: &'static str,
     /// Name for display in the progress bar.
     short_name: String,
+    /// Pad the short name to a common width for progress bar use.
+    short_name_padded: String,
     total_tests: u64,
     /// Function to launch this test.
-    launch: fn(&mpsc::Sender<Msg>, &TestInfo, &Config),
+    launch: fn(&TestInfo, &Config),
     /// Progress bar to be updated.
-    pb: Option<ProgressBar>,
+    progress: Option<ui::Progress>,
     /// Once completed, this will be set.
     completed: OnceLock<Completed>,
 }
@@ -187,14 +187,18 @@ impl TestInfo {
         let f_name = type_name::<F>();
         let gen_name = G::NAME;
         let gen_short_name = G::SHORT_NAME;
+        let name = format!("{f_name} {gen_name}");
+        let short_name = format!("{f_name} {gen_short_name}");
+        let short_name_padded = format!("{short_name:18}");
 
         let info = TestInfo {
-            id: TypeId::of::<(F, G)>(),
             float_name: f_name,
+            float_bits: F::BITS,
             gen_name,
-            pb: None,
-            name: format!("{f_name} {gen_name}"),
-            short_name: format!("{f_name} {gen_short_name}"),
+            progress: None,
+            name,
+            short_name_padded,
+            short_name,
             launch: test_runner::<F, G>,
             total_tests: G::total_tests(),
             completed: OnceLock::new(),
@@ -202,106 +206,18 @@ impl TestInfo {
         v.push(info);
     }
 
-    /// Pad the short name to a common width for progress bar use.
-    fn short_name_padded(&self) -> String {
-        format!("{:18}", self.short_name)
-    }
-
-    /// Create a progress bar for this test within a multiprogress bar.
-    fn register_pb(&mut self, mp: &MultiProgress, drop_bars: &mut Vec<ProgressBar>) {
-        self.pb = Some(ui::create_pb(mp, self.total_tests, &self.short_name_padded(), drop_bars));
-    }
-
-    /// When the test is finished, update progress bar messages and finalize.
-    fn finalize_pb(&self, c: &Completed) {
-        let pb = self.pb.as_ref().unwrap();
-        ui::finalize_pb(pb, &self.short_name_padded(), c);
-    }
-
     /// True if this should be run after all others.
     fn is_huge_test(&self) -> bool {
         self.total_tests >= HUGE_TEST_CUTOFF
     }
-}
-
-/// A message sent from test runner threads to the UI/log thread.
-#[derive(Clone, Debug)]
-struct Msg {
-    id: TypeId,
-    update: Update,
-}
 
-impl Msg {
-    /// Wrap an `Update` into a message for the specified type. We use the `TypeId` of `(F, G)` to
-    /// identify which test a message in the channel came from.
-    fn new<F: Float, G: Generator<F>>(u: Update) -> Self {
-        Self { id: TypeId::of::<(F, G)>(), update: u }
-    }
-
-    /// Get the matching test from a list. Panics if not found.
-    fn find_test<'a>(&self, tests: &'a [TestInfo]) -> &'a TestInfo {
-        tests.iter().find(|t| t.id == self.id).unwrap()
-    }
-
-    /// Update UI as needed for a single message received from the test runners.
-    fn handle(self, tests: &[TestInfo], mp: &MultiProgress) {
-        let test = self.find_test(tests);
-        let pb = test.pb.as_ref().unwrap();
-
-        match self.update {
-            Update::Started => {
-                mp.println(format!("Testing '{}'", test.name)).unwrap();
-            }
-            Update::Progress { executed, failures } => {
-                pb.set_message(format! {"{failures}"});
-                pb.set_position(executed);
-            }
-            Update::Failure { fail, input, float_res } => {
-                mp.println(format!(
-                    "Failure in '{}': {fail}. parsing '{input}'. Parsed as: {float_res}",
-                    test.name
-                ))
-                .unwrap();
-            }
-            Update::Completed(c) => {
-                test.finalize_pb(&c);
-
-                let prefix = match c.result {
-                    Ok(FinishedAll) => "Completed tests for",
-                    Err(EarlyExit::Timeout) => "Timed out",
-                    Err(EarlyExit::MaxFailures) => "Max failures reached for",
-                };
-
-                mp.println(format!(
-                    "{prefix} generator '{}' in {:?}. {} tests run, {} failures",
-                    test.name, c.elapsed, c.executed, c.failures
-                ))
-                .unwrap();
-                test.completed.set(c).unwrap();
-            }
-        };
+    /// When the test is finished, update progress bar messages and finalize.
+    fn complete(&self, c: Completed) {
+        self.progress.as_ref().unwrap().complete(&c, 0);
+        self.completed.set(c).unwrap();
     }
 }
 
-/// Status sent with a message.
-#[derive(Clone, Debug)]
-enum Update {
-    /// Starting a new test runner.
-    Started,
-    /// Completed a out of b tests.
-    Progress { executed: u64, failures: u64 },
-    /// Received a failed test.
-    Failure {
-        fail: CheckFailure,
-        /// String for which parsing was attempted.
-        input: Box<str>,
-        /// The parsed & decomposed `FloatRes`, already stringified so we don't need generics here.
-        float_res: Box<str>,
-    },
-    /// Exited with an unexpected condition.
-    Completed(Completed),
-}
-
 /// Result of an input did not parsing successfully.
 #[derive(Clone, Debug)]
 enum CheckFailure {
@@ -329,6 +245,10 @@ enum CheckFailure {
         /// two representable values.
         incorrect_midpoint_rounding: bool,
     },
+    /// String did not parse successfully.
+    ParsingFailed(Box<str>),
+    /// A panic was caught.
+    Panic(Box<str>),
 }
 
 impl fmt::Display for CheckFailure {
@@ -363,6 +283,8 @@ impl fmt::Display for CheckFailure {
                 }
                 Ok(())
             }
+            CheckFailure::ParsingFailed(e) => write!(f, "parsing failed: {e}"),
+            CheckFailure::Panic(e) => write!(f, "function panicked: {e}"),
         }
     }
 }
@@ -398,55 +320,21 @@ enum EarlyExit {
 /// This launches a main thread that receives messages and handlees UI updates, and uses the
 /// rest of the thread pool to execute the tests.
 fn launch_tests(tests: &mut [TestInfo], cfg: &Config) -> Duration {
-    // Run shorter tests first
-    tests.sort_unstable_by_key(|test| test.total_tests);
+    // Run shorter tests and smaller float types first.
+    tests.sort_unstable_by_key(|test| (test.total_tests, test.float_bits));
 
     for test in tests.iter() {
         println!("Launching test '{}'", test.name);
     }
 
-    // Configure progress bars
     let mut all_progress_bars = Vec::new();
-    let mp = MultiProgress::new();
-    mp.set_move_cursor(true);
-    for test in tests.iter_mut() {
-        test.register_pb(&mp, &mut all_progress_bars);
-    }
-
-    ui::set_panic_hook(all_progress_bars);
-
-    let (tx, rx) = mpsc::channel::<Msg>();
     let start = Instant::now();
 
-    rayon::scope(|scope| {
-        // Thread that updates the UI
-        scope.spawn(|_scope| {
-            let rx = rx; // move rx
-
-            loop {
-                if tests.iter().all(|t| t.completed.get().is_some()) {
-                    break;
-                }
-
-                let msg = rx.recv().unwrap();
-                msg.handle(tests, &mp);
-            }
-
-            // All tests completed; finish things up
-            drop(mp);
-            assert_eq!(rx.try_recv().unwrap_err(), mpsc::TryRecvError::Empty);
-        });
-
-        // Don't let the thread pool be starved by huge tests. Run faster tests first in parallel,
-        // then parallelize only within the rest of the tests.
-        let (huge_tests, normal_tests): (Vec<_>, Vec<_>) =
-            tests.iter().partition(|t| t.is_huge_test());
-
-        // Run the actual tests
-        normal_tests.par_iter().for_each(|test| ((test.launch)(&tx, test, cfg)));
-
-        huge_tests.par_iter().for_each(|test| ((test.launch)(&tx, test, cfg)));
-    });
+    for test in tests.iter_mut() {
+        test.progress = Some(ui::Progress::new(test, &mut all_progress_bars));
+        ui::set_panic_hook(&all_progress_bars);
+        ((test.launch)(test, cfg));
+    }
 
     start.elapsed()
 }
@@ -454,15 +342,12 @@ fn launch_tests(tests: &mut [TestInfo], cfg: &Config) -> Duration {
 /// Test runer for a single generator.
 ///
 /// This calls the generator's iterator multiple times (in parallel) and validates each output.
-fn test_runner<F: Float, G: Generator<F>>(tx: &mpsc::Sender<Msg>, _info: &TestInfo, cfg: &Config) {
-    tx.send(Msg::new::<F, G>(Update::Started)).unwrap();
-
-    let total = G::total_tests();
+fn test_runner<F: Float, G: Generator<F>>(test: &TestInfo, cfg: &Config) {
     let gen = G::new();
     let executed = AtomicU64::new(0);
     let failures = AtomicU64::new(0);
 
-    let checks_per_update = min(total, 1000);
+    let checks_per_update = min(test.total_tests, 1000);
     let started = Instant::now();
 
     // Function to execute for a single test iteration.
@@ -474,7 +359,12 @@ fn test_runner<F: Float, G: Generator<F>>(tx: &mpsc::Sender<Msg>, _info: &TestIn
         match validate::validate::<F>(buf) {
             Ok(()) => (),
             Err(e) => {
-                tx.send(Msg::new::<F, G>(e)).unwrap();
+                let CheckError { fail, input, float_res } = e;
+                test.progress.as_ref().unwrap().println(&format!(
+                    "Failure in '{}': {fail}. parsing '{input}'. Parsed as: {float_res}",
+                    test.name
+                ));
+
                 let f = failures.fetch_add(1, Ordering::Relaxed);
                 // End early if the limit is exceeded.
                 if f >= cfg.max_failures {
@@ -486,9 +376,7 @@ fn test_runner<F: Float, G: Generator<F>>(tx: &mpsc::Sender<Msg>, _info: &TestIn
         // Send periodic updates
         if executed % checks_per_update == 0 {
             let failures = failures.load(Ordering::Relaxed);
-
-            tx.send(Msg::new::<F, G>(Update::Progress { executed, failures })).unwrap();
-
+            test.progress.as_ref().unwrap().update(executed, failures);
             if started.elapsed() > cfg.timeout {
                 return Err(EarlyExit::Timeout);
             }
@@ -499,15 +387,19 @@ fn test_runner<F: Float, G: Generator<F>>(tx: &mpsc::Sender<Msg>, _info: &TestIn
 
     // Run the test iterations in parallel. Each thread gets a string buffer to write
     // its check values to.
-    let res = gen.par_bridge().try_for_each_init(|| String::with_capacity(100), check_one);
+    let res = gen.par_bridge().try_for_each_init(String::new, check_one);
 
     let elapsed = started.elapsed();
     let executed = executed.into_inner();
     let failures = failures.into_inner();
 
     // Warn about bad estimates if relevant.
-    let warning = if executed != total && res.is_ok() {
-        let msg = format!("executed tests != estimated ({executed} != {total}) for {}", G::NAME);
+    let warning = if executed != test.total_tests && res.is_ok() {
+        let msg = format!(
+            "executed tests != estimated ({executed} != {}) for {}",
+            test.total_tests,
+            G::NAME
+        );
 
         Some(msg.into())
     } else {
@@ -515,12 +407,5 @@ fn test_runner<F: Float, G: Generator<F>>(tx: &mpsc::Sender<Msg>, _info: &TestIn
     };
 
     let result = res.map(|()| FinishedAll);
-    tx.send(Msg::new::<F, G>(Update::Completed(Completed {
-        executed,
-        failures,
-        result,
-        warning,
-        elapsed,
-    })))
-    .unwrap();
+    test.complete(Completed { executed, failures, result, warning, elapsed });
 }
diff --git a/src/etc/test-float-parse/src/traits.rs b/src/etc/test-float-parse/src/traits.rs
index f5333d63b36..c8407ba7cc5 100644
--- a/src/etc/test-float-parse/src/traits.rs
+++ b/src/etc/test-float-parse/src/traits.rs
@@ -177,7 +177,7 @@ impl_float!(f32, u32, 32; f64, u64, 64);
 /// allocations (which otherwise turn out to be a pretty expensive part of these tests).
 pub trait Generator<F: Float>: Iterator<Item = Self::WriteCtx> + Send + 'static {
     /// Full display and filtering name
-    const NAME: &'static str;
+    const NAME: &'static str = Self::SHORT_NAME;
 
     /// Name for display with the progress bar
     const SHORT_NAME: &'static str;
diff --git a/src/etc/test-float-parse/src/ui.rs b/src/etc/test-float-parse/src/ui.rs
index f333bd4a55d..1ee57723e6a 100644
--- a/src/etc/test-float-parse/src/ui.rs
+++ b/src/etc/test-float-parse/src/ui.rs
@@ -1,67 +1,92 @@
 //! Progress bars and such.
 
+use std::any::type_name;
+use std::fmt;
 use std::io::{self, Write};
 use std::process::ExitCode;
 use std::time::Duration;
 
-use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
+use indicatif::{ProgressBar, ProgressStyle};
 
 use crate::{Completed, Config, EarlyExit, FinishedAll, TestInfo};
 
 /// Templates for progress bars.
-const PB_TEMPLATE: &str = "[{elapsed:3} {percent:3}%] {bar:20.cyan/blue} NAME ({pos}/{len}, {msg} f, {per_sec}, eta {eta})";
-const PB_TEMPLATE_FINAL: &str =
-    "[{elapsed:3} {percent:3}%] NAME ({pos}/{len}, {msg:.COLOR}, {per_sec}, {elapsed_precise})";
-
-/// Create a new progress bar within a multiprogress bar.
-pub fn create_pb(
-    mp: &MultiProgress,
-    total_tests: u64,
-    short_name_padded: &str,
-    all_bars: &mut Vec<ProgressBar>,
-) -> ProgressBar {
-    let pb = mp.add(ProgressBar::new(total_tests));
-    let pb_style = ProgressStyle::with_template(&PB_TEMPLATE.replace("NAME", short_name_padded))
-        .unwrap()
-        .progress_chars("##-");
-
-    pb.set_style(pb_style.clone());
-    pb.set_message("0");
-    all_bars.push(pb.clone());
-    pb
+const PB_TEMPLATE: &str = "[{elapsed:3} {percent:3}%] {bar:20.cyan/blue} NAME \
+        {human_pos:>8}/{human_len:8} {msg} f {per_sec:14} eta {eta:8}";
+const PB_TEMPLATE_FINAL: &str = "[{elapsed:3} {percent:3}%] {bar:20.cyan/blue} NAME \
+        {human_pos:>8}/{human_len:8} {msg:.COLOR} {per_sec:18} {elapsed_precise}";
+
+/// Thin abstraction over our usage of a `ProgressBar`.
+#[derive(Debug)]
+pub struct Progress {
+    pb: ProgressBar,
+    make_final_style: NoDebug<Box<dyn Fn(&'static str) -> ProgressStyle + Sync>>,
 }
 
-/// Removes the status bar and replace it with a message.
-pub fn finalize_pb(pb: &ProgressBar, short_name_padded: &str, c: &Completed) {
-    let f = c.failures;
+impl Progress {
+    /// Create a new progress bar within a multiprogress bar.
+    pub fn new(test: &TestInfo, all_bars: &mut Vec<ProgressBar>) -> Self {
+        let initial_template = PB_TEMPLATE.replace("NAME", &test.short_name_padded);
+        let final_template = PB_TEMPLATE_FINAL.replace("NAME", &test.short_name_padded);
+        let initial_style =
+            ProgressStyle::with_template(&initial_template).unwrap().progress_chars("##-");
+        let make_final_style = move |color| {
+            ProgressStyle::with_template(&final_template.replace("COLOR", color))
+                .unwrap()
+                .progress_chars("##-")
+        };
 
-    // Use a tuple so we can use colors
-    let (color, msg, finish_pb): (&str, String, fn(&ProgressBar, String)) = match &c.result {
-        Ok(FinishedAll) if f > 0 => {
-            ("red", format!("{f} f (finished with errors)",), ProgressBar::finish_with_message)
-        }
-        Ok(FinishedAll) => {
-            ("green", format!("{f} f (finished successfully)",), ProgressBar::finish_with_message)
-        }
-        Err(EarlyExit::Timeout) => {
-            ("red", format!("{f} f (timed out)"), ProgressBar::abandon_with_message)
+        let pb = ProgressBar::new(test.total_tests);
+        pb.set_style(initial_style);
+        pb.set_length(test.total_tests);
+        pb.set_message("0");
+        all_bars.push(pb.clone());
+
+        Progress { pb, make_final_style: NoDebug(Box::new(make_final_style)) }
+    }
+
+    /// Completed a out of b tests.
+    pub fn update(&self, completed: u64, failures: u64) {
+        // Infrequently update the progress bar.
+        if completed % 5_000 == 0 || failures > 0 {
+            self.pb.set_position(completed);
         }
-        Err(EarlyExit::MaxFailures) => {
-            ("red", format!("{f} f (failure limit)"), ProgressBar::abandon_with_message)
+
+        if failures > 0 {
+            self.pb.set_message(format! {"{failures}"});
         }
-    };
+    }
+
+    /// Finalize the progress bar.
+    pub fn complete(&self, c: &Completed, real_total: u64) {
+        let f = c.failures;
+        let (color, msg, finish_fn): (&str, String, fn(&ProgressBar)) = match &c.result {
+            Ok(FinishedAll) if f > 0 => {
+                ("red", format!("{f} f (completed with errors)",), ProgressBar::finish)
+            }
+            Ok(FinishedAll) => {
+                ("green", format!("{f} f (completed successfully)",), ProgressBar::finish)
+            }
+            Err(EarlyExit::Timeout) => ("red", format!("{f} f (timed out)"), ProgressBar::abandon),
+            Err(EarlyExit::MaxFailures) => {
+                ("red", format!("{f} f (failure limit)"), ProgressBar::abandon)
+            }
+        };
 
-    let pb_style = ProgressStyle::with_template(
-        &PB_TEMPLATE_FINAL.replace("NAME", short_name_padded).replace("COLOR", color),
-    )
-    .unwrap();
+        self.pb.set_position(real_total);
+        self.pb.set_style(self.make_final_style.0(color));
+        self.pb.set_message(msg);
+        finish_fn(&self.pb);
+    }
 
-    pb.set_style(pb_style);
-    finish_pb(pb, msg);
+    /// Print a message to stdout above the current progress bar.
+    pub fn println(&self, msg: &str) {
+        self.pb.suspend(|| println!("{msg}"));
+    }
 }
 
 /// Print final messages after all tests are complete.
-pub fn finish(tests: &[TestInfo], total_elapsed: Duration, cfg: &Config) -> ExitCode {
+pub fn finish_all(tests: &[TestInfo], total_elapsed: Duration, cfg: &Config) -> ExitCode {
     println!("\n\nResults:");
 
     let mut failed_generators = 0;
@@ -118,8 +143,9 @@ pub fn finish(tests: &[TestInfo], total_elapsed: Duration, cfg: &Config) -> Exit
 
 /// indicatif likes to eat panic messages. This workaround isn't ideal, but it improves things.
 /// <https://github.com/console-rs/indicatif/issues/121>.
-pub fn set_panic_hook(drop_bars: Vec<ProgressBar>) {
+pub fn set_panic_hook(drop_bars: &[ProgressBar]) {
     let hook = std::panic::take_hook();
+    let drop_bars = drop_bars.to_owned();
     std::panic::set_hook(Box::new(move |info| {
         for bar in &drop_bars {
             bar.abandon();
@@ -130,3 +156,13 @@ pub fn set_panic_hook(drop_bars: Vec<ProgressBar>) {
         hook(info);
     }));
 }
+
+/// Allow non-Debug items in a `derive(Debug)` struct`.
+#[derive(Clone)]
+struct NoDebug<T>(T);
+
+impl<T> fmt::Debug for NoDebug<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str(type_name::<Self>())
+    }
+}
diff --git a/src/etc/test-float-parse/src/validate.rs b/src/etc/test-float-parse/src/validate.rs
index 1eb3699cfb9..40dda274e3b 100644
--- a/src/etc/test-float-parse/src/validate.rs
+++ b/src/etc/test-float-parse/src/validate.rs
@@ -1,6 +1,6 @@
 //! Everything related to verifying that parsed outputs are correct.
 
-use std::any::type_name;
+use std::any::{Any, type_name};
 use std::collections::BTreeMap;
 use std::ops::RangeInclusive;
 use std::str::FromStr;
@@ -9,7 +9,7 @@ use std::sync::LazyLock;
 use num::bigint::ToBigInt;
 use num::{BigInt, BigRational, FromPrimitive, Signed, ToPrimitive};
 
-use crate::{CheckFailure, Float, Int, Update};
+use crate::{CheckFailure, Float, Int};
 
 /// Powers of two that we store for constants. Account for binary128 which has a 15-bit exponent.
 const POWERS_OF_TWO_RANGE: RangeInclusive<i32> = (-(2 << 15))..=(2 << 15);
@@ -89,10 +89,16 @@ impl Constants {
 }
 
 /// Validate that a string parses correctly
-pub fn validate<F: Float>(input: &str) -> Result<(), Update> {
-    let parsed: F = input
-        .parse()
-        .unwrap_or_else(|e| panic!("parsing failed for {}: {e}. Input: {input}", type_name::<F>()));
+pub fn validate<F: Float>(input: &str) -> Result<(), CheckError> {
+    // Catch panics in case debug assertions within `std` fail.
+    let parsed = std::panic::catch_unwind(|| {
+        input.parse::<F>().map_err(|e| CheckError {
+            fail: CheckFailure::ParsingFailed(e.to_string().into()),
+            input: input.into(),
+            float_res: "none".into(),
+        })
+    })
+    .map_err(|e| convert_panic_error(&e, input))??;
 
     // Parsed float, decoded into significand and exponent
     let decoded = decode(parsed);
@@ -104,6 +110,21 @@ pub fn validate<F: Float>(input: &str) -> Result<(), Update> {
     decoded.check(rational, input)
 }
 
+/// Turn panics into concrete error types.
+fn convert_panic_error(e: &dyn Any, input: &str) -> CheckError {
+    let msg = e
+        .downcast_ref::<String>()
+        .map(|s| s.as_str())
+        .or_else(|| e.downcast_ref::<&str>().copied())
+        .unwrap_or("(no contents)");
+
+    CheckError {
+        fail: CheckFailure::Panic(msg.into()),
+        input: input.into(),
+        float_res: "none".into(),
+    }
+}
+
 /// The result of parsing a string to a float type.
 #[derive(Clone, Copy, Debug, PartialEq)]
 pub enum FloatRes<F: Float> {
@@ -118,10 +139,19 @@ pub enum FloatRes<F: Float> {
     },
 }
 
+#[derive(Clone, Debug)]
+pub struct CheckError {
+    pub fail: CheckFailure,
+    /// String for which parsing was attempted.
+    pub input: Box<str>,
+    /// The parsed & decomposed `FloatRes`, already stringified so we don't need generics here.
+    pub float_res: Box<str>,
+}
+
 impl<F: Float> FloatRes<F> {
     /// Given a known exact rational, check that this representation is accurate within the
     /// limits of the float representation. If not, construct a failure `Update` to send.
-    fn check(self, expected: Rational, input: &str) -> Result<(), Update> {
+    fn check(self, expected: Rational, input: &str) -> Result<(), CheckError> {
         let consts = F::constants();
         // let bool_helper = |cond: bool, err| cond.then_some(()).ok_or(err);
 
@@ -173,7 +203,7 @@ impl<F: Float> FloatRes<F> {
             (Rational::Finite(r), FloatRes::Real { sig, exp }) => Self::validate_real(r, sig, exp),
         };
 
-        res.map_err(|fail| Update::Failure {
+        res.map_err(|fail| CheckError {
             fail,
             input: input.into(),
             float_res: format!("{self:?}").into(),
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
index ab5f97199ce..4f024ecaf29 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
@@ -682,19 +682,20 @@ pub fn eq_generics(l: &Generics, r: &Generics) -> bool {
 
 pub fn eq_where_predicate(l: &WherePredicate, r: &WherePredicate) -> bool {
     use WherePredicateKind::*;
-    match (&l.kind, &r.kind) {
-        (BoundPredicate(l), BoundPredicate(r)) => {
-            over(&l.bound_generic_params, &r.bound_generic_params, |l, r| {
-                eq_generic_param(l, r)
-            }) && eq_ty(&l.bounded_ty, &r.bounded_ty)
-                && over(&l.bounds, &r.bounds, eq_generic_bound)
-        },
-        (RegionPredicate(l), RegionPredicate(r)) => {
-            eq_id(l.lifetime.ident, r.lifetime.ident) && over(&l.bounds, &r.bounds, eq_generic_bound)
-        },
-        (EqPredicate(l), EqPredicate(r)) => eq_ty(&l.lhs_ty, &r.lhs_ty) && eq_ty(&l.rhs_ty, &r.rhs_ty),
-        _ => false,
-    }
+    over(&l.attrs, &r.attrs, eq_attr) 
+        && match (&l.kind, &r.kind) {
+            (BoundPredicate(l), BoundPredicate(r)) => {
+                over(&l.bound_generic_params, &r.bound_generic_params, |l, r| {
+                    eq_generic_param(l, r)
+                }) && eq_ty(&l.bounded_ty, &r.bounded_ty)
+                    && over(&l.bounds, &r.bounds, eq_generic_bound)
+            },
+            (RegionPredicate(l), RegionPredicate(r)) => {
+                eq_id(l.lifetime.ident, r.lifetime.ident) && over(&l.bounds, &r.bounds, eq_generic_bound)
+            },
+            (EqPredicate(l), EqPredicate(r)) => eq_ty(&l.lhs_ty, &r.lhs_ty) && eq_ty(&l.rhs_ty, &r.rhs_ty),
+            _ => false,
+        }
 }
 
 pub fn eq_use_tree(l: &UseTree, r: &UseTree) -> bool {
diff --git a/src/tools/rustfmt/src/spanned.rs b/src/tools/rustfmt/src/spanned.rs
index e93eb53cd87..507647566d4 100644
--- a/src/tools/rustfmt/src/spanned.rs
+++ b/src/tools/rustfmt/src/spanned.rs
@@ -58,6 +58,7 @@ implement_spanned!(ast::ExprField);
 implement_spanned!(ast::ForeignItem);
 implement_spanned!(ast::Item);
 implement_spanned!(ast::Local);
+implement_spanned!(ast::WherePredicate);
 
 impl Spanned for ast::Stmt {
     fn span(&self) -> Span {
@@ -149,12 +150,6 @@ impl Spanned for ast::FieldDef {
     }
 }
 
-impl Spanned for ast::WherePredicate {
-    fn span(&self) -> Span {
-        self.span
-    }
-}
-
 impl Spanned for ast::FnRetTy {
     fn span(&self) -> Span {
         match *self {
diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs
index 7b44b47c719..06a67334086 100644
--- a/src/tools/rustfmt/src/types.rs
+++ b/src/tools/rustfmt/src/types.rs
@@ -463,8 +463,9 @@ impl Rewrite for ast::WherePredicate {
     }
 
     fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
+        let attrs_str = self.attrs.rewrite_result(context, shape)?;
         // FIXME: dead spans?
-        let result = match self.kind {
+        let pred_str = &match self.kind {
             ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate {
                 ref bound_generic_params,
                 ref bounded_ty,
@@ -499,6 +500,38 @@ impl Rewrite for ast::WherePredicate {
             }
         };
 
+        let mut result = String::with_capacity(attrs_str.len() + pred_str.len() + 1);
+        result.push_str(&attrs_str);
+        let pred_start = self.span.lo();
+        let line_len = last_line_width(&attrs_str) + 1 + first_line_width(&pred_str);
+        if let Some(last_attr) = self.attrs.last().filter(|last_attr| {
+            contains_comment(context.snippet(mk_sp(last_attr.span.hi(), pred_start)))
+        }) {
+            result = combine_strs_with_missing_comments(
+                context,
+                &result,
+                &pred_str,
+                mk_sp(last_attr.span.hi(), pred_start),
+                Shape {
+                    width: shape.width.min(context.config.inline_attribute_width()),
+                    ..shape
+                },
+                !last_attr.is_doc_comment(),
+            )?;
+        } else {
+            if !self.attrs.is_empty() {
+                if context.config.inline_attribute_width() < line_len
+                    || self.attrs.len() > 1
+                    || self.attrs.last().is_some_and(|a| a.is_doc_comment())
+                {
+                    result.push_str(&shape.indent.to_string_with_newline(context.config));
+                } else {
+                    result.push(' ');
+                }
+            }
+            result.push_str(&pred_str);
+        }
+
         Ok(result)
     }
 }
diff --git a/src/tools/rustfmt/tests/target/cfg_attribute_in_where.rs b/src/tools/rustfmt/tests/target/cfg_attribute_in_where.rs
new file mode 100644
index 00000000000..11f495b1629
--- /dev/null
+++ b/src/tools/rustfmt/tests/target/cfg_attribute_in_where.rs
@@ -0,0 +1,116 @@
+// rustfmt-inline_attribute_width: 40
+
+#![crate_type = "lib"]
+#![feature(cfg_attribute_in_where)]
+use std::marker::PhantomData;
+
+#[cfg(a)]
+trait TraitA {}
+
+#[cfg(b)]
+trait TraitB {}
+
+trait A<T>
+where
+    #[cfg = a_very_long_attribute_name]
+    T: TraitA,
+    #[cfg = another_very_long_attribute_name]
+    T: TraitB,
+{
+    type B<U>
+    where
+        #[cfg = a]
+        // line comment after the attribute
+        U: TraitA,
+        #[cfg = b]
+        /* block comment after the attribute */
+        U: TraitB,
+        #[cfg = a] // short
+        U: TraitA,
+        #[cfg = b] /* short */ U: TraitB;
+
+    fn foo<U>(&self)
+    where
+        /// line doc comment before the attribute
+        U: TraitA,
+        /** line doc block comment before the attribute */
+        U: TraitB;
+}
+
+impl<T> A<T> for T
+where
+    #[doc = "line doc before the attribute"]
+    T: TraitA,
+    /** short doc */
+    T: TraitB,
+{
+    type B<U>
+        = ()
+    where
+        #[doc = "short"] U: TraitA,
+        #[doc = "short"]
+        #[cfg = a]
+        U: TraitB;
+
+    fn foo<U>(&self)
+    where
+        #[cfg = a]
+        #[cfg = b]
+        U: TraitA,
+        /// line doc
+        #[cfg = c]
+        U: TraitB,
+    {
+    }
+}
+
+struct C<T>
+where
+    #[cfg = a] T: TraitA,
+    #[cfg = b] T: TraitB,
+{
+    _t: PhantomData<T>,
+}
+
+union D<T>
+where
+    #[cfg = a] T: TraitA,
+    #[cfg = b] T: TraitB,
+{
+    _t: PhantomData<T>,
+}
+
+enum E<T>
+where
+    #[cfg = a] T: TraitA,
+    #[cfg = b] T: TraitB,
+{
+    E(PhantomData<T>),
+}
+
+#[allow(type_alias_bounds)]
+type F<T>
+where
+    #[cfg = a] T: TraitA,
+    #[cfg = b] T: TraitB,
+= T;
+
+impl<T> C<T>
+where
+    #[cfg = a] T: TraitA,
+    #[cfg = b] T: TraitB,
+{
+    fn new<U>()
+    where
+        #[cfg = a] U: TraitA,
+        #[cfg = b] U: TraitB,
+    {
+    }
+}
+
+fn foo<T>()
+where
+    #[cfg = a] T: TraitA,
+    #[cfg = b] T: TraitB,
+{
+}
diff --git a/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs b/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs
index 57fc601a2e0..91c83fa2f5b 100644
--- a/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs
+++ b/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs
@@ -19,7 +19,7 @@
 #![allow(incomplete_features)]
 #![feature(unsized_locals, unsized_fn_params)]
 
-// CHECK-LABEL: emptyfn:
+// CHECK-LABEL: emptyfn{{:|\[}}
 #[no_mangle]
 pub fn emptyfn() {
     // all: __stack_chk_fail
@@ -29,7 +29,7 @@ pub fn emptyfn() {
     // missing-NOT: __stack_chk_fail
 }
 
-// CHECK-LABEL: array_char
+// CHECK-LABEL: array_char{{:|\[}}
 #[no_mangle]
 pub fn array_char(f: fn(*const char)) {
     let a = ['c'; 1];
@@ -47,7 +47,7 @@ pub fn array_char(f: fn(*const char)) {
     // missing-NOT: __stack_chk_fail
 }
 
-// CHECK-LABEL: array_u8_1
+// CHECK-LABEL: array_u8_1{{:|\[}}
 #[no_mangle]
 pub fn array_u8_1(f: fn(*const u8)) {
     let a = [0u8; 1];
@@ -63,7 +63,7 @@ pub fn array_u8_1(f: fn(*const u8)) {
     // missing-NOT: __stack_chk_fail
 }
 
-// CHECK-LABEL: array_u8_small:
+// CHECK-LABEL: array_u8_small{{:|\[}}
 #[no_mangle]
 pub fn array_u8_small(f: fn(*const u8)) {
     let a = [0u8; 2];
@@ -80,7 +80,7 @@ pub fn array_u8_small(f: fn(*const u8)) {
     // missing-NOT: __stack_chk_fail
 }
 
-// CHECK-LABEL: array_u8_large:
+// CHECK-LABEL: array_u8_large{{:|\[}}
 #[no_mangle]
 pub fn array_u8_large(f: fn(*const u8)) {
     let a = [0u8; 9];
@@ -99,7 +99,7 @@ pub fn array_u8_large(f: fn(*const u8)) {
 #[derive(Copy, Clone)]
 pub struct ByteSizedNewtype(u8);
 
-// CHECK-LABEL: array_bytesizednewtype_9:
+// CHECK-LABEL: array_bytesizednewtype_9{{:|\[}}
 #[no_mangle]
 pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) {
     let a = [ByteSizedNewtype(0); 9];
@@ -115,7 +115,7 @@ pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) {
     // missing-NOT: __stack_chk_fail
 }
 
-// CHECK-LABEL: local_var_addr_used_indirectly
+// CHECK-LABEL: local_var_addr_used_indirectly{{:|\[}}
 #[no_mangle]
 pub fn local_var_addr_used_indirectly(f: fn(bool)) {
     let a = 5;
@@ -142,7 +142,7 @@ pub fn local_var_addr_used_indirectly(f: fn(bool)) {
     // missing-NOT: __stack_chk_fail
 }
 
-// CHECK-LABEL: local_string_addr_taken
+// CHECK-LABEL: local_string_addr_taken{{:|\[}}
 #[no_mangle]
 pub fn local_string_addr_taken(f: fn(&String)) {
     let x = String::new();
@@ -168,7 +168,7 @@ impl SelfByRef for i32 {
     }
 }
 
-// CHECK-LABEL: local_var_addr_taken_used_locally_only
+// CHECK-LABEL: local_var_addr_taken_used_locally_only{{:|\[}}
 #[no_mangle]
 pub fn local_var_addr_taken_used_locally_only(factory: fn() -> i32, sink: fn(i32)) {
     let x = factory();
@@ -195,7 +195,7 @@ pub struct Gigastruct {
     members: u64,
 }
 
-// CHECK-LABEL: local_large_var_moved
+// CHECK-LABEL: local_large_var_moved{{:|\[}}
 #[no_mangle]
 pub fn local_large_var_moved(f: fn(Gigastruct)) {
     let x = Gigastruct { does: 0, not: 1, have: 2, array: 3, members: 4 };
@@ -224,7 +224,7 @@ pub fn local_large_var_moved(f: fn(Gigastruct)) {
     // missing-NOT: __stack_chk_fail
 }
 
-// CHECK-LABEL: local_large_var_cloned
+// CHECK-LABEL: local_large_var_cloned{{:|\[}}
 #[no_mangle]
 pub fn local_large_var_cloned(f: fn(Gigastruct)) {
     f(Gigastruct { does: 0, not: 1, have: 2, array: 3, members: 4 });
@@ -281,7 +281,7 @@ extern "C" {
     fn alloca(size: usize) -> *mut ();
 }
 
-// CHECK-LABEL: alloca_small_compile_time_constant_arg
+// CHECK-LABEL: alloca_small_compile_time_constant_arg{{:|\[}}
 #[no_mangle]
 pub fn alloca_small_compile_time_constant_arg(f: fn(*mut ())) {
     f(unsafe { alloca(8) });
@@ -293,7 +293,7 @@ pub fn alloca_small_compile_time_constant_arg(f: fn(*mut ())) {
     // missing-NOT: __stack_chk_fail
 }
 
-// CHECK-LABEL: alloca_large_compile_time_constant_arg
+// CHECK-LABEL: alloca_large_compile_time_constant_arg{{:|\[}}
 #[no_mangle]
 pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) {
     f(unsafe { alloca(9) });
@@ -305,7 +305,7 @@ pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) {
     // missing-NOT: __stack_chk_fail
 }
 
-// CHECK-LABEL: alloca_dynamic_arg
+// CHECK-LABEL: alloca_dynamic_arg{{:|\[}}
 #[no_mangle]
 pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) {
     f(unsafe { alloca(n) });
@@ -324,7 +324,7 @@ pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) {
 // this is support for the "unsized locals" unstable feature:
 // https://doc.rust-lang.org/unstable-book/language-features/unsized-locals.html.
 
-// CHECK-LABEL: unsized_fn_param
+// CHECK-LABEL: unsized_fn_param{{:|\[}}
 #[no_mangle]
 pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) {
     let n = if l { 1 } else { 2 };
@@ -344,7 +344,7 @@ pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) {
     // missing-NOT: __stack_chk_fail
 }
 
-// CHECK-LABEL: unsized_local
+// CHECK-LABEL: unsized_local{{:|\[}}
 #[no_mangle]
 pub fn unsized_local(s: &[u8], l: bool, f: fn(&mut [u8])) {
     let n = if l { 1 } else { 2 };
diff --git a/tests/run-make/rustc-help/help-v.stdout b/tests/run-make/rustc-help/help-v.stdout
index 382b1c96682..c8ea09ee2c8 100644
--- a/tests/run-make/rustc-help/help-v.stdout
+++ b/tests/run-make/rustc-help/help-v.stdout
@@ -29,7 +29,7 @@ Options:
         --emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]
                         Comma separated list of types of output for the
                         compiler to emit
-        --print [crate-name|file-names|sysroot|target-libdir|cfg|check-cfg|calling-conventions|target-list|target-cpus|target-features|relocation-models|code-models|tls-models|target-spec-json|all-target-specs-json|native-static-libs|stack-protector-strategies|link-args|deployment-target]
+        --print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models]
                         Compiler information to print on stdout
     -g                  Equivalent to -C debuginfo=2
     -O                  Equivalent to -C opt-level=3
diff --git a/tests/run-make/rustc-help/help.stdout b/tests/run-make/rustc-help/help.stdout
index 08bb7f85098..434e71e901e 100644
--- a/tests/run-make/rustc-help/help.stdout
+++ b/tests/run-make/rustc-help/help.stdout
@@ -29,7 +29,7 @@ Options:
         --emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]
                         Comma separated list of types of output for the
                         compiler to emit
-        --print [crate-name|file-names|sysroot|target-libdir|cfg|check-cfg|calling-conventions|target-list|target-cpus|target-features|relocation-models|code-models|tls-models|target-spec-json|all-target-specs-json|native-static-libs|stack-protector-strategies|link-args|deployment-target]
+        --print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models]
                         Compiler information to print on stdout
     -g                  Equivalent to -C debuginfo=2
     -O                  Equivalent to -C opt-level=3
diff --git a/tests/ui/feature-gates/feature-gate-where_clause_attrs.a.stderr b/tests/ui/feature-gates/feature-gate-where_clause_attrs.a.stderr
new file mode 100644
index 00000000000..6a8f01bbcce
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-where_clause_attrs.a.stderr
@@ -0,0 +1,883 @@
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:33:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:34:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:35:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:36:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:37:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:38:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:39:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:40:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:44:9
+   |
+LL |         #[cfg(a)] U: TraitA,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:45:9
+   |
+LL |         #[cfg(b)] U: TraitB,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:46:9
+   |
+LL |         #[cfg(all())] U: TraitAll,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:47:9
+   |
+LL |         #[cfg(any())] U: TraitAny,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:48:9
+   |
+LL |         #[cfg_attr(a, cfg(a))] U: TraitAA,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:49:9
+   |
+LL |         #[cfg_attr(b, cfg(b))] U: TraitBB,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:50:9
+   |
+LL |         #[cfg_attr(all(), cfg(all()))] U: TraitAllAll,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:51:9
+   |
+LL |         #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:55:9
+   |
+LL |         #[cfg(a)] U: TraitA,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:56:9
+   |
+LL |         #[cfg(b)] U: TraitB,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:57:9
+   |
+LL |         #[cfg(all())] U: TraitAll,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:58:9
+   |
+LL |         #[cfg(any())] U: TraitAny,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:59:9
+   |
+LL |         #[cfg_attr(a, cfg(a))] U: TraitAA,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:60:9
+   |
+LL |         #[cfg_attr(b, cfg(b))] U: TraitBB,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:61:9
+   |
+LL |         #[cfg_attr(all(), cfg(all()))] U: TraitAllAll,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:62:9
+   |
+LL |         #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:67:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:68:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:69:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:70:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:71:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:72:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:73:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:74:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:77:9
+   |
+LL |         #[cfg(a)] U: TraitA,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:78:9
+   |
+LL |         #[cfg(b)] U: TraitB,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:79:9
+   |
+LL |         #[cfg(all())] U: TraitAll,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:80:9
+   |
+LL |         #[cfg(any())] U: TraitAny,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:81:9
+   |
+LL |         #[cfg_attr(a, cfg(a))] U: TraitAA,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:82:9
+   |
+LL |         #[cfg_attr(b, cfg(b))] U: TraitBB,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:83:9
+   |
+LL |         #[cfg_attr(all(), cfg(all()))] U: TraitAllAll,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:84:9
+   |
+LL |         #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:88:9
+   |
+LL |         #[cfg(a)] U: TraitA,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:89:9
+   |
+LL |         #[cfg(b)] U: TraitB,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:90:9
+   |
+LL |         #[cfg(all())] T: TraitAll,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:91:9
+   |
+LL |         #[cfg(any())] T: TraitAny,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:92:9
+   |
+LL |         #[cfg_attr(a, cfg(a))] U: TraitAA,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:93:9
+   |
+LL |         #[cfg_attr(b, cfg(b))] U: TraitBB,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:94:9
+   |
+LL |         #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:95:9
+   |
+LL |         #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:101:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:102:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:103:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:104:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:105:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:106:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:107:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:108:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:115:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:116:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:117:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:118:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:119:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:120:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:121:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:122:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:130:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:131:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:132:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:133:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:134:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:135:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:136:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:137:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:143:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:144:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:145:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:146:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:147:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:148:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:149:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:150:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:153:9
+   |
+LL |         #[cfg(a)] U: TraitA,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:154:9
+   |
+LL |         #[cfg(b)] U: TraitB,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:155:9
+   |
+LL |         #[cfg(all())] U: TraitAll,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:156:9
+   |
+LL |         #[cfg(any())] U: TraitAny,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:157:9
+   |
+LL |         #[cfg_attr(a, cfg(a))] U: TraitAA,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:158:9
+   |
+LL |         #[cfg_attr(b, cfg(b))] U: TraitBB,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:159:9
+   |
+LL |         #[cfg_attr(all(), cfg(all()))] U: TraitAllAll,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:160:9
+   |
+LL |         #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 88 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-where_clause_attrs.b.stderr b/tests/ui/feature-gates/feature-gate-where_clause_attrs.b.stderr
new file mode 100644
index 00000000000..6a8f01bbcce
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-where_clause_attrs.b.stderr
@@ -0,0 +1,883 @@
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:33:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:34:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:35:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:36:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:37:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:38:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:39:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:40:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:44:9
+   |
+LL |         #[cfg(a)] U: TraitA,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:45:9
+   |
+LL |         #[cfg(b)] U: TraitB,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:46:9
+   |
+LL |         #[cfg(all())] U: TraitAll,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:47:9
+   |
+LL |         #[cfg(any())] U: TraitAny,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:48:9
+   |
+LL |         #[cfg_attr(a, cfg(a))] U: TraitAA,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:49:9
+   |
+LL |         #[cfg_attr(b, cfg(b))] U: TraitBB,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:50:9
+   |
+LL |         #[cfg_attr(all(), cfg(all()))] U: TraitAllAll,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:51:9
+   |
+LL |         #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:55:9
+   |
+LL |         #[cfg(a)] U: TraitA,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:56:9
+   |
+LL |         #[cfg(b)] U: TraitB,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:57:9
+   |
+LL |         #[cfg(all())] U: TraitAll,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:58:9
+   |
+LL |         #[cfg(any())] U: TraitAny,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:59:9
+   |
+LL |         #[cfg_attr(a, cfg(a))] U: TraitAA,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:60:9
+   |
+LL |         #[cfg_attr(b, cfg(b))] U: TraitBB,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:61:9
+   |
+LL |         #[cfg_attr(all(), cfg(all()))] U: TraitAllAll,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:62:9
+   |
+LL |         #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:67:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:68:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:69:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:70:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:71:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:72:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:73:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:74:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:77:9
+   |
+LL |         #[cfg(a)] U: TraitA,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:78:9
+   |
+LL |         #[cfg(b)] U: TraitB,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:79:9
+   |
+LL |         #[cfg(all())] U: TraitAll,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:80:9
+   |
+LL |         #[cfg(any())] U: TraitAny,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:81:9
+   |
+LL |         #[cfg_attr(a, cfg(a))] U: TraitAA,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:82:9
+   |
+LL |         #[cfg_attr(b, cfg(b))] U: TraitBB,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:83:9
+   |
+LL |         #[cfg_attr(all(), cfg(all()))] U: TraitAllAll,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:84:9
+   |
+LL |         #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:88:9
+   |
+LL |         #[cfg(a)] U: TraitA,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:89:9
+   |
+LL |         #[cfg(b)] U: TraitB,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:90:9
+   |
+LL |         #[cfg(all())] T: TraitAll,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:91:9
+   |
+LL |         #[cfg(any())] T: TraitAny,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:92:9
+   |
+LL |         #[cfg_attr(a, cfg(a))] U: TraitAA,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:93:9
+   |
+LL |         #[cfg_attr(b, cfg(b))] U: TraitBB,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:94:9
+   |
+LL |         #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:95:9
+   |
+LL |         #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:101:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:102:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:103:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:104:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:105:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:106:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:107:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:108:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:115:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:116:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:117:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:118:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:119:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:120:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:121:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:122:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:130:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:131:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:132:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:133:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:134:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:135:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:136:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:137:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:143:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:144:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:145:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:146:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:147:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:148:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:149:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:150:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:153:9
+   |
+LL |         #[cfg(a)] U: TraitA,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:154:9
+   |
+LL |         #[cfg(b)] U: TraitB,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:155:9
+   |
+LL |         #[cfg(all())] U: TraitAll,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:156:9
+   |
+LL |         #[cfg(any())] U: TraitAny,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:157:9
+   |
+LL |         #[cfg_attr(a, cfg(a))] U: TraitAA,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:158:9
+   |
+LL |         #[cfg_attr(b, cfg(b))] U: TraitBB,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:159:9
+   |
+LL |         #[cfg_attr(all(), cfg(all()))] U: TraitAllAll,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:160:9
+   |
+LL |         #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 88 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-where_clause_attrs.rs b/tests/ui/feature-gates/feature-gate-where_clause_attrs.rs
new file mode 100644
index 00000000000..09c734a52de
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-where_clause_attrs.rs
@@ -0,0 +1,162 @@
+//@ revisions: a b
+
+#![crate_type = "lib"]
+use std::marker::PhantomData;
+
+#[cfg(a)]
+trait TraitA {}
+
+#[cfg(b)]
+trait TraitB {}
+
+#[cfg_attr(a, cfg(a))]
+trait TraitAA {}
+
+#[cfg_attr(b, cfg(b))]
+trait TraitBB {}
+
+#[cfg(all())]
+trait TraitAll {}
+
+#[cfg(any())]
+trait TraitAny {}
+
+#[cfg_attr(all(), cfg(all()))]
+trait TraitAllAll {}
+
+#[cfg_attr(any(), cfg(any()))]
+trait TraitAnyAny {}
+
+
+trait A<T>
+where
+    #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable
+{
+    type B<U>
+    where
+        #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(all())] U: TraitAll, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(any())] U: TraitAny, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; //~ ERROR attributes in `where` clause are unstable
+
+    fn foo<U>(&self)
+    where
+        #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(all())] U: TraitAll, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(any())] U: TraitAny, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; //~ ERROR attributes in `where` clause are unstable
+}
+
+impl<T> A<T> for T
+where
+    #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable
+{
+    type B<U> = () where
+        #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(all())] U: TraitAll, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(any())] U: TraitAny, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; //~ ERROR attributes in `where` clause are unstable
+
+    fn foo<U>(&self)
+    where
+        #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable
+    {}
+}
+
+struct C<T>
+where
+    #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable
+{
+    _t: PhantomData<T>,
+}
+
+union D<T>
+where
+    #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable
+{
+
+    _t: PhantomData<T>,
+}
+
+enum E<T>
+where
+    #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable
+{
+    E(PhantomData<T>),
+}
+
+impl<T> C<T> where
+    #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable
+{
+    fn new<U>() where
+        #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(all())] U: TraitAll, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(any())] U: TraitAny, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable
+    {}
+}
diff --git a/tests/ui/invalid-compile-flags/print-without-arg.stderr b/tests/ui/invalid-compile-flags/print-without-arg.stderr
index a18d2779cad..05d42247d41 100644
--- a/tests/ui/invalid-compile-flags/print-without-arg.stderr
+++ b/tests/ui/invalid-compile-flags/print-without-arg.stderr
@@ -1,5 +1,5 @@
 error: Argument to option 'print' missing
        Usage:
-           --print [crate-name|file-names|sysroot|target-libdir|cfg|check-cfg|calling-conventions|target-list|target-cpus|target-features|relocation-models|code-models|tls-models|target-spec-json|all-target-specs-json|native-static-libs|stack-protector-strategies|link-args|deployment-target]
+           --print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models]
                                Compiler information to print on stdout
 
diff --git a/tests/ui/parser/bounds-lifetime-where.rs b/tests/ui/parser/bounds-lifetime-where.rs
index 7ff75233d3a..730be7139be 100644
--- a/tests/ui/parser/bounds-lifetime-where.rs
+++ b/tests/ui/parser/bounds-lifetime-where.rs
@@ -5,6 +5,6 @@ type A where 'a:, = u8; // OK
 type A where 'a: 'b + 'c = u8; // OK
 type A where = u8; // OK
 type A where 'a: 'b + = u8; // OK
-type A where , = u8; //~ ERROR expected one of `;`, `=`, `where`, lifetime, or type, found `,`
+type A where , = u8; //~ ERROR expected one of `#`, `;`, `=`, `where`, lifetime, or type, found `,`
 
 fn main() {}
diff --git a/tests/ui/parser/bounds-lifetime-where.stderr b/tests/ui/parser/bounds-lifetime-where.stderr
index 9dd963afc79..5aadb5fff32 100644
--- a/tests/ui/parser/bounds-lifetime-where.stderr
+++ b/tests/ui/parser/bounds-lifetime-where.stderr
@@ -1,8 +1,8 @@
-error: expected one of `;`, `=`, `where`, lifetime, or type, found `,`
+error: expected one of `#`, `;`, `=`, `where`, lifetime, or type, found `,`
   --> $DIR/bounds-lifetime-where.rs:8:14
    |
 LL | type A where , = u8;
-   |              ^ expected one of `;`, `=`, `where`, lifetime, or type
+   |              ^ expected one of `#`, `;`, `=`, `where`, lifetime, or type
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/issues/misplaced-return-type-where-in-next-line-issue-126311.stderr b/tests/ui/parser/issues/misplaced-return-type-where-in-next-line-issue-126311.stderr
index 196a46d7ea5..6245f81d533 100644
--- a/tests/ui/parser/issues/misplaced-return-type-where-in-next-line-issue-126311.stderr
+++ b/tests/ui/parser/issues/misplaced-return-type-where-in-next-line-issue-126311.stderr
@@ -2,7 +2,7 @@ error: return type should be specified after the function parameters
   --> $DIR/misplaced-return-type-where-in-next-line-issue-126311.rs:5:15
    |
 LL |     K: Clone, -> Result<u8, String>
-   |               ^^ expected one of `{`, lifetime, or type
+   |               ^^ expected one of `#`, `{`, lifetime, or type
    |
 help: place the return type after the function parameters
    |
diff --git a/tests/ui/parser/ranges-precedence.rs b/tests/ui/parser/ranges-precedence.rs
index 14dd6488ff2..783799f7099 100644
--- a/tests/ui/parser/ranges-precedence.rs
+++ b/tests/ui/parser/ranges-precedence.rs
@@ -1,7 +1,8 @@
 //@ run-pass
+//@ edition: 2021
 // Test that the precedence of ranges is correct
 
-
+use core::ops::{Add, RangeTo};
 
 struct Foo {
     foo: usize,
@@ -11,6 +12,13 @@ impl Foo {
     fn bar(&self) -> usize { 5 }
 }
 
+impl Add<RangeTo<usize>> for Foo {
+    type Output = usize;
+    fn add(self, range: RangeTo<usize>) -> Self::Output {
+        self.foo + range.end
+    }
+}
+
 fn main() {
     let x = 1+3..4+5;
     assert_eq!(x, (4..9));
@@ -49,4 +57,22 @@ fn main() {
 
     let y = ..;
     assert_eq!(y, (..));
+
+    let reference = &..0;
+    assert_eq!(*reference, ..0);
+    let reference2 = &&..0;
+    assert_eq!(**reference2, ..0);
+
+    let closure = || ..0;
+    assert_eq!(closure(), ..0);
+
+    let sum = Foo { foo: 3 } + ..4;
+    assert_eq!(sum, 7);
+
+    macro_rules! expr {
+        ($e:expr) => {};
+    }
+    expr!(!..0);
+    expr!(-..0);
+    expr!(*..0);
 }
diff --git a/tests/ui/stats/input-stats.stderr b/tests/ui/stats/input-stats.stderr
index 9b1568fa116..dbc9e7d254c 100644
--- a/tests/ui/stats/input-stats.stderr
+++ b/tests/ui/stats/input-stats.stderr
@@ -8,8 +8,8 @@ ast-stats-1 ExprField                 48 ( 0.7%)             1            48
 ast-stats-1 Attribute                 64 ( 1.0%)             2            32
 ast-stats-1 - DocComment                32 ( 0.5%)             1
 ast-stats-1 - Normal                    32 ( 0.5%)             1
-ast-stats-1 WherePredicate            64 ( 1.0%)             1            64
-ast-stats-1 - BoundPredicate            64 ( 1.0%)             1
+ast-stats-1 WherePredicate            72 ( 1.1%)             1            72
+ast-stats-1 - BoundPredicate            72 ( 1.1%)             1
 ast-stats-1 Local                     80 ( 1.2%)             1            80
 ast-stats-1 ForeignItem               88 ( 1.3%)             1            88
 ast-stats-1 - Fn                        88 ( 1.3%)             1
@@ -37,14 +37,14 @@ ast-stats-1 Expr                     576 ( 8.6%)             8            72
 ast-stats-1 - Match                     72 ( 1.1%)             1
 ast-stats-1 - Path                      72 ( 1.1%)             1
 ast-stats-1 - Struct                    72 ( 1.1%)             1
-ast-stats-1 - Lit                      144 ( 2.2%)             2
+ast-stats-1 - Lit                      144 ( 2.1%)             2
 ast-stats-1 - Block                    216 ( 3.2%)             3
 ast-stats-1 PathSegment              744 (11.1%)            31            24
 ast-stats-1 Ty                       896 (13.4%)            14            64
 ast-stats-1 - Ptr                       64 ( 1.0%)             1
 ast-stats-1 - Ref                       64 ( 1.0%)             1
 ast-stats-1 - ImplicitSelf             128 ( 1.9%)             2
-ast-stats-1 - Path                     640 ( 9.6%)            10
+ast-stats-1 - Path                     640 ( 9.5%)            10
 ast-stats-1 Item                   1_224 (18.3%)             9           136
 ast-stats-1 - Enum                     136 ( 2.0%)             1
 ast-stats-1 - ForeignMod               136 ( 2.0%)             1
@@ -53,7 +53,7 @@ ast-stats-1 - Trait                    136 ( 2.0%)             1
 ast-stats-1 - Fn                       272 ( 4.1%)             2
 ast-stats-1 - Use                      408 ( 6.1%)             3
 ast-stats-1 ----------------------------------------------------------------
-ast-stats-1 Total                  6_696                   116
+ast-stats-1 Total                  6_704                   116
 ast-stats-1
 ast-stats-2 POST EXPANSION AST STATS
 ast-stats-2 Name                Accumulated Size         Count     Item Size
@@ -62,8 +62,8 @@ ast-stats-2 Crate                     40 ( 0.5%)             1            40
 ast-stats-2 GenericArgs               40 ( 0.5%)             1            40
 ast-stats-2 - AngleBracketed            40 ( 0.5%)             1
 ast-stats-2 ExprField                 48 ( 0.7%)             1            48
-ast-stats-2 WherePredicate            64 ( 0.9%)             1            64
-ast-stats-2 - BoundPredicate            64 ( 0.9%)             1
+ast-stats-2 WherePredicate            72 ( 1.0%)             1            72
+ast-stats-2 - BoundPredicate            72 ( 1.0%)             1
 ast-stats-2 Local                     80 ( 1.1%)             1            80
 ast-stats-2 ForeignItem               88 ( 1.2%)             1            88
 ast-stats-2 - Fn                        88 ( 1.2%)             1
@@ -104,16 +104,16 @@ ast-stats-2 - Ptr                       64 ( 0.9%)             1
 ast-stats-2 - Ref                       64 ( 0.9%)             1
 ast-stats-2 - ImplicitSelf             128 ( 1.7%)             2
 ast-stats-2 - Path                     640 ( 8.7%)            10
-ast-stats-2 Item                   1_496 (20.4%)            11           136
-ast-stats-2 - Enum                     136 ( 1.9%)             1
-ast-stats-2 - ExternCrate              136 ( 1.9%)             1
-ast-stats-2 - ForeignMod               136 ( 1.9%)             1
-ast-stats-2 - Impl                     136 ( 1.9%)             1
-ast-stats-2 - Trait                    136 ( 1.9%)             1
+ast-stats-2 Item                   1_496 (20.3%)            11           136
+ast-stats-2 - Enum                     136 ( 1.8%)             1
+ast-stats-2 - ExternCrate              136 ( 1.8%)             1
+ast-stats-2 - ForeignMod               136 ( 1.8%)             1
+ast-stats-2 - Impl                     136 ( 1.8%)             1
+ast-stats-2 - Trait                    136 ( 1.8%)             1
 ast-stats-2 - Fn                       272 ( 3.7%)             2
 ast-stats-2 - Use                      544 ( 7.4%)             4
 ast-stats-2 ----------------------------------------------------------------
-ast-stats-2 Total                  7_344                   127
+ast-stats-2 Total                  7_352                   127
 ast-stats-2
 hir-stats HIR STATS
 hir-stats Name                Accumulated Size         Count     Item Size
diff --git a/tests/ui/where-clauses/cfg_attribute.a.stderr b/tests/ui/where-clauses/cfg_attribute.a.stderr
new file mode 100644
index 00000000000..0ede890eb44
--- /dev/null
+++ b/tests/ui/where-clauses/cfg_attribute.a.stderr
@@ -0,0 +1,288 @@
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:32:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:43:11
+   |
+LL |         #[derive(Clone)] ():,
+   |           ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:54:11
+   |
+LL |         #[derive(Clone)] ():,
+   |           ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:66:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:76:11
+   |
+LL |         #[derive(Clone)] ():,
+   |           ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:87:11
+   |
+LL |         #[derive(Clone)] ():,
+   |           ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:100:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:114:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:129:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:144:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:155:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:165:11
+   |
+LL |         #[derive(Clone)] ():,
+   |           ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:178:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:32:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:35:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:66:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:69:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:100:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:103:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:114:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:117:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:129:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:132:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:144:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:147:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:155:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:158:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:178:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:181:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:43:9
+   |
+LL |         #[derive(Clone)] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:46:9
+   |
+LL |         #[rustfmt::skip] ():;
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:54:9
+   |
+LL |         #[derive(Clone)] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:57:9
+   |
+LL |         #[rustfmt::skip] ():;
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:76:9
+   |
+LL |         #[derive(Clone)] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:79:9
+   |
+LL |         #[rustfmt::skip] ():;
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:87:9
+   |
+LL |         #[derive(Clone)] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:90:9
+   |
+LL |         #[rustfmt::skip] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:165:9
+   |
+LL |         #[derive(Clone)] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:168:9
+   |
+LL |         #[rustfmt::skip] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: aborting due to 39 previous errors
+
diff --git a/tests/ui/where-clauses/cfg_attribute.b.stderr b/tests/ui/where-clauses/cfg_attribute.b.stderr
new file mode 100644
index 00000000000..0ede890eb44
--- /dev/null
+++ b/tests/ui/where-clauses/cfg_attribute.b.stderr
@@ -0,0 +1,288 @@
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:32:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:43:11
+   |
+LL |         #[derive(Clone)] ():,
+   |           ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:54:11
+   |
+LL |         #[derive(Clone)] ():,
+   |           ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:66:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:76:11
+   |
+LL |         #[derive(Clone)] ():,
+   |           ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:87:11
+   |
+LL |         #[derive(Clone)] ():,
+   |           ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:100:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:114:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:129:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:144:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:155:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:165:11
+   |
+LL |         #[derive(Clone)] ():,
+   |           ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:178:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:32:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:35:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:66:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:69:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:100:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:103:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:114:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:117:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:129:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:132:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:144:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:147:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:155:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:158:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:178:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:181:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:43:9
+   |
+LL |         #[derive(Clone)] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:46:9
+   |
+LL |         #[rustfmt::skip] ():;
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:54:9
+   |
+LL |         #[derive(Clone)] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:57:9
+   |
+LL |         #[rustfmt::skip] ():;
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:76:9
+   |
+LL |         #[derive(Clone)] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:79:9
+   |
+LL |         #[rustfmt::skip] ():;
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:87:9
+   |
+LL |         #[derive(Clone)] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:90:9
+   |
+LL |         #[rustfmt::skip] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:165:9
+   |
+LL |         #[derive(Clone)] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:168:9
+   |
+LL |         #[rustfmt::skip] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: aborting due to 39 previous errors
+
diff --git a/tests/ui/where-clauses/cfg_attribute.rs b/tests/ui/where-clauses/cfg_attribute.rs
new file mode 100644
index 00000000000..8cbca0bee75
--- /dev/null
+++ b/tests/ui/where-clauses/cfg_attribute.rs
@@ -0,0 +1,183 @@
+//@ revisions: a b
+
+#![crate_type = "lib"]
+#![feature(alloc_error_handler)]
+#![feature(cfg_accessible)]
+#![feature(cfg_eval)]
+#![feature(custom_test_frameworks)]
+#![feature(derive_const)]
+#![feature(where_clause_attrs)]
+#![allow(soft_unstable)]
+
+use std::marker::PhantomData;
+
+#[cfg(a)]
+trait TraitA {}
+
+#[cfg(b)]
+trait TraitB {}
+
+#[cfg_attr(a, cfg(a))]
+trait TraitAA {}
+
+#[cfg_attr(b, cfg(b))]
+trait TraitBB {}
+
+trait A<T>
+where
+    #[cfg(a)] T: TraitA,
+    #[cfg(b)] T: TraitB,
+    #[cfg_attr(a, cfg(a))] T: TraitAA,
+    #[cfg_attr(b, cfg(b))] T: TraitBB,
+    #[derive(Clone)] ():,
+    //~^ ERROR most attributes are not supported in `where` clauses
+    //~| ERROR expected non-macro attribute, found attribute macro `derive`
+    #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses
+{
+    type B<U>
+    where
+        #[cfg(a)] U: TraitA,
+        #[cfg(b)] U: TraitB,
+        #[cfg_attr(a, cfg(a))] U: TraitAA,
+        #[cfg_attr(b, cfg(b))] U: TraitBB,
+        #[derive(Clone)] ():,
+        //~^ ERROR most attributes are not supported in `where` clauses
+        //~| ERROR expected non-macro attribute, found attribute macro `derive`
+        #[rustfmt::skip] ():; //~ ERROR most attributes are not supported in `where` clauses
+
+    fn foo<U>(&self)
+    where
+        #[cfg(a)] U: TraitA,
+        #[cfg(b)] U: TraitB,
+        #[cfg_attr(a, cfg(a))] U: TraitAA,
+        #[cfg_attr(b, cfg(b))] U: TraitBB,
+        #[derive(Clone)] ():,
+        //~^ ERROR most attributes are not supported in `where` clauses
+        //~| ERROR expected non-macro attribute, found attribute macro `derive`
+        #[rustfmt::skip] ():; //~ ERROR most attributes are not supported in `where` clauses
+}
+
+impl<T> A<T> for T
+where
+    #[cfg(a)] T: TraitA,
+    #[cfg(b)] T: TraitB,
+    #[cfg_attr(a, cfg(a))] T: TraitAA,
+    #[cfg_attr(b, cfg(b))] T: TraitBB,
+    #[derive(Clone)] ():,
+    //~^ ERROR most attributes are not supported in `where` clauses
+    //~| ERROR expected non-macro attribute, found attribute macro `derive`
+    #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses
+{
+    type B<U> = () where
+        #[cfg(a)] U: TraitA,
+        #[cfg(b)] U: TraitB,
+        #[cfg_attr(a, cfg(a))] U: TraitAA,
+        #[cfg_attr(b, cfg(b))] U: TraitBB,
+        #[derive(Clone)] ():,
+        //~^ ERROR most attributes are not supported in `where` clauses
+        //~| ERROR expected non-macro attribute, found attribute macro `derive`
+        #[rustfmt::skip] ():; //~ ERROR most attributes are not supported in `where` clauses
+
+    fn foo<U>(&self)
+    where
+        #[cfg(a)] U: TraitA,
+        #[cfg(b)] U: TraitB,
+        #[cfg_attr(a, cfg(a))] U: TraitAA,
+        #[cfg_attr(b, cfg(b))] U: TraitBB,
+        #[derive(Clone)] ():,
+        //~^ ERROR most attributes are not supported in `where` clauses
+        //~| ERROR expected non-macro attribute, found attribute macro `derive`
+        #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses
+    {}
+}
+
+struct C<T>
+where
+    #[cfg(a)] T: TraitA,
+    #[cfg(b)] T: TraitB,
+    #[cfg_attr(a, cfg(a))] T: TraitAA,
+    #[cfg_attr(b, cfg(b))] T: TraitBB,
+    #[derive(Clone)] ():,
+    //~^ ERROR most attributes are not supported in `where` clauses
+    //~| ERROR expected non-macro attribute, found attribute macro `derive`
+    #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses
+{
+    _t: PhantomData<T>,
+}
+
+union D<T>
+where
+    #[cfg(a)] T: TraitA,
+    #[cfg(b)] T: TraitB,
+    #[cfg_attr(a, cfg(a))] T: TraitAA,
+    #[cfg_attr(b, cfg(b))] T: TraitBB,
+    #[derive(Clone)] ():,
+    //~^ ERROR most attributes are not supported in `where` clauses
+    //~| ERROR expected non-macro attribute, found attribute macro `derive`
+    #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses
+{
+
+    _t: PhantomData<T>,
+}
+
+enum E<T>
+where
+    #[cfg(a)] T: TraitA,
+    #[cfg(b)] T: TraitB,
+    #[cfg_attr(a, cfg(a))] T: TraitAA,
+    #[cfg_attr(b, cfg(b))] T: TraitBB,
+    #[derive(Clone)] ():,
+    //~^ ERROR most attributes are not supported in `where` clauses
+    //~| ERROR expected non-macro attribute, found attribute macro `derive`
+    #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses
+{
+    E(PhantomData<T>),
+}
+
+#[allow(type_alias_bounds)]
+type F<T>
+where
+    #[cfg(a)] T: TraitA,
+    #[cfg(b)] T: TraitB,
+    #[cfg_attr(a, cfg(a))] T: TraitAA,
+    #[cfg_attr(b, cfg(b))] T: TraitBB,
+    #[derive(Clone)] ():,
+    //~^ ERROR most attributes are not supported in `where` clauses
+    //~| ERROR expected non-macro attribute, found attribute macro `derive`
+    #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses
+= T;
+
+impl<T> C<T> where
+    #[cfg(a)] T: TraitA,
+    #[cfg(b)] T: TraitB,
+    #[cfg_attr(a, cfg(a))] T: TraitAA,
+    #[cfg_attr(b, cfg(b))] T: TraitBB,
+    #[derive(Clone)] ():,
+    //~^ ERROR most attributes are not supported in `where` clauses
+    //~| ERROR expected non-macro attribute, found attribute macro `derive`
+    #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses
+{
+    fn new<U>() where
+        #[cfg(a)] U: TraitA,
+        #[cfg(b)] U: TraitB,
+        #[cfg_attr(a, cfg(a))] U: TraitAA,
+        #[cfg_attr(b, cfg(b))] U: TraitBB,
+        #[derive(Clone)] ():,
+        //~^ ERROR most attributes are not supported in `where` clauses
+        //~| ERROR expected non-macro attribute, found attribute macro `derive`
+        #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses
+    {}
+}
+
+fn foo<T>()
+where
+    #[cfg(a)] T: TraitA,
+    #[cfg(b)] T: TraitB,
+    #[cfg_attr(a, cfg(a))] T: TraitAA,
+    #[cfg_attr(b, cfg(b))] T: TraitBB,
+    #[derive(Clone)] ():,
+    //~^ ERROR most attributes are not supported in `where` clauses
+    //~| ERROR expected non-macro attribute, found attribute macro `derive`
+    #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses
+{
+}
diff --git a/tests/ui/where-clauses/unsupported_attribute.rs b/tests/ui/where-clauses/unsupported_attribute.rs
new file mode 100644
index 00000000000..33128b383b9
--- /dev/null
+++ b/tests/ui/where-clauses/unsupported_attribute.rs
@@ -0,0 +1,36 @@
+#![crate_type = "lib"]
+#![feature(alloc_error_handler)]
+#![feature(cfg_accessible)]
+#![feature(cfg_eval)]
+#![feature(custom_test_frameworks)]
+#![feature(derive_const)]
+#![feature(where_clause_attrs)]
+#![allow(soft_unstable)]
+
+trait Trait {}
+
+fn foo<'a, T>()
+where
+    #[doc = "doc"] T: Trait, //~ ERROR most attributes are not supported in `where` clauses
+    #[doc = "doc"] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses
+    #[ignore] T: Trait, //~ ERROR most attributes are not supported in `where` clauses
+    #[ignore] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses
+    #[should_panic] T: Trait, //~ ERROR most attributes are not supported in `where` clauses
+    #[should_panic] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses
+    #[macro_use] T: Trait, //~ ERROR most attributes are not supported in `where` clauses
+    #[macro_use] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses
+    #[allow(unused)] T: Trait, //~ ERROR most attributes are not supported in `where` clauses
+    #[allow(unused)] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses
+    #[deprecated] T: Trait, //~ ERROR most attributes are not supported in `where` clauses
+    #[deprecated] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses
+    #[automatically_derived] T: Trait, //~ ERROR most attributes are not supported in `where` clauses
+    #[automatically_derived] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses
+    #[derive(Clone)] T: Trait,
+    //~^ ERROR most attributes are not supported in `where` clauses
+    //~| ERROR expected non-macro attribute, found attribute macro `derive`
+    #[derive(Clone)] 'a: 'static,
+    //~^ ERROR most attributes are not supported in `where` clauses
+    //~| ERROR expected non-macro attribute, found attribute macro `derive`
+    #[rustfmt::skip] T: Trait, //~ ERROR most attributes are not supported in `where` clauses
+    #[rustfmt::skip] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses
+{}
diff --git a/tests/ui/where-clauses/unsupported_attribute.stderr b/tests/ui/where-clauses/unsupported_attribute.stderr
new file mode 100644
index 00000000000..ecb28039f88
--- /dev/null
+++ b/tests/ui/where-clauses/unsupported_attribute.stderr
@@ -0,0 +1,158 @@
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/unsupported_attribute.rs:28:7
+   |
+LL |     #[derive(Clone)] T: Trait,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/unsupported_attribute.rs:31:7
+   |
+LL |     #[derive(Clone)] 'a: 'static,
+   |       ^^^^^^ not a non-macro attribute
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:14:5
+   |
+LL |     #[doc = "doc"] T: Trait,
+   |     ^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:15:5
+   |
+LL |     #[doc = "doc"] 'a: 'static,
+   |     ^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:16:5
+   |
+LL |     #[ignore] T: Trait,
+   |     ^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:17:5
+   |
+LL |     #[ignore] 'a: 'static,
+   |     ^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:18:5
+   |
+LL |     #[should_panic] T: Trait,
+   |     ^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:19:5
+   |
+LL |     #[should_panic] 'a: 'static,
+   |     ^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:20:5
+   |
+LL |     #[macro_use] T: Trait,
+   |     ^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:21:5
+   |
+LL |     #[macro_use] 'a: 'static,
+   |     ^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:22:5
+   |
+LL |     #[allow(unused)] T: Trait,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:23:5
+   |
+LL |     #[allow(unused)] 'a: 'static,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:24:5
+   |
+LL |     #[deprecated] T: Trait,
+   |     ^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:25:5
+   |
+LL |     #[deprecated] 'a: 'static,
+   |     ^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:26:5
+   |
+LL |     #[automatically_derived] T: Trait,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:27:5
+   |
+LL |     #[automatically_derived] 'a: 'static,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:28:5
+   |
+LL |     #[derive(Clone)] T: Trait,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:31:5
+   |
+LL |     #[derive(Clone)] 'a: 'static,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:34:5
+   |
+LL |     #[rustfmt::skip] T: Trait,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:35:5
+   |
+LL |     #[rustfmt::skip] 'a: 'static,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: aborting due to 20 previous errors
+