From d0cdfab44c2322792d0512c5040513ac4df89e87 Mon Sep 17 00:00:00 2001 From: Frank King Date: Mon, 11 Nov 2024 15:27:49 +0800 Subject: [PATCH] Implment `#[cfg]` in `where` clauses --- compiler/rustc_ast/src/ast.rs | 2 + compiler/rustc_ast/src/ast_traits.rs | 15 +- compiler/rustc_ast/src/mut_visit.rs | 3 +- compiler/rustc_ast/src/visit.rs | 3 +- compiler/rustc_ast_lowering/src/item.rs | 1 + compiler/rustc_ast_passes/src/feature_gate.rs | 1 + .../rustc_ast_pretty/src/pprust/state/item.rs | 3 +- compiler/rustc_builtin_macros/src/cfg_eval.rs | 4 + .../src/deriving/generic/mod.rs | 8 +- compiler/rustc_expand/src/base.rs | 18 +- compiler/rustc_expand/src/expand.rs | 38 +- compiler/rustc_expand/src/placeholders.rs | 13 + compiler/rustc_feature/src/unstable.rs | 2 + compiler/rustc_hir_pretty/src/lib.rs | 1 + compiler/rustc_parse/src/parser/generics.rs | 75 ++-- compiler/rustc_passes/messages.ftl | 4 + compiler/rustc_passes/src/check_attr.rs | 22 + compiler/rustc_passes/src/errors.rs | 8 + compiler/rustc_span/src/symbol.rs | 1 + .../clippy/clippy_utils/src/ast_utils.rs | 27 +- src/tools/rustfmt/src/types.rs | 35 +- .../tests/target/cfg_attribute_in_where.rs | 116 +++++ ...ature-gate-cfg_attribute_in_where.a.stderr | 413 ++++++++++++++++++ ...ature-gate-cfg_attribute_in_where.b.stderr | 413 ++++++++++++++++++ .../feature-gate-cfg_attribute_in_where.rs | 101 +++++ tests/ui/parser/bounds-lifetime-where.rs | 2 +- tests/ui/parser/bounds-lifetime-where.stderr | 4 +- ...ype-where-in-next-line-issue-126311.stderr | 2 +- tests/ui/stats/hir-stats.stderr | 16 +- tests/ui/where-clauses/cfg_attribute.rs | 91 ++++ .../ui/where-clauses/unsupported_attribute.rs | 28 ++ .../unsupported_attribute.stderr | 162 +++++++ 32 files changed, 1566 insertions(+), 66 deletions(-) create mode 100644 src/tools/rustfmt/tests/target/cfg_attribute_in_where.rs create mode 100644 tests/ui/feature-gates/feature-gate-cfg_attribute_in_where.a.stderr create mode 100644 tests/ui/feature-gates/feature-gate-cfg_attribute_in_where.b.stderr create mode 100644 tests/ui/feature-gates/feature-gate-cfg_attribute_in_where.rs create mode 100644 tests/ui/where-clauses/cfg_attribute.rs create mode 100644 tests/ui/where-clauses/unsupported_attribute.rs create mode 100644 tests/ui/where-clauses/unsupported_attribute.stderr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 6af20d26238fb..fd2ab9ab4df63 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -429,6 +429,7 @@ impl Default for 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, @@ -444,6 +445,7 @@ impl WherePredicate { f: impl FnOnce(&WherePredicateKind) -> WherePredicateKind, ) -> WherePredicate { WherePredicate { + attrs: self.attrs.clone(), kind: f(&self.kind), id: DUMMY_NODE_ID, span: ctxt.map_or(self.span, |ctxt| self.span.with_ctxt(ctxt)), diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs index 60f8c6e10481b..c4d16e80cad2d 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> 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> HasTokens for T { fn tokens(&self) -> Option<&LazyAttrTokenStream> { @@ -289,6 +299,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 28f2b92950745..da68112c2bd6b 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1002,8 +1002,9 @@ pub fn walk_flat_map_where_predicate( vis: &mut T, mut pred: WherePredicate, ) -> SmallVec<[WherePredicate; 1]> { - let WherePredicate { ref mut kind, ref mut id, ref mut span } = pred; + let WherePredicate { ref mut attrs, ref mut kind, ref mut id, ref mut span } = pred; vis.visit_id(id); + visit_attrs(vis, attrs); vis.visit_where_predicate_kind(kind); vis.visit_span(span); smallvec![pred] diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index b35572bed7292..197fc266a9ce8 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -789,7 +789,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: _ } = 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 2ddb3d933d21f..d766dc7c27970 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1579,6 +1579,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); + self.lower_attrs(hir_id, &pred.attrs); let kind = 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 a1c7a4165455c..677aa59270ae0 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -547,6 +547,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { gate_all!(global_registration, "global registration is experimental"); gate_all!(return_type_notation, "return type notation is experimental"); gate_all!(pin_ergonomics, "pinned reference syntax is experimental"); + gate_all!(cfg_attribute_in_where, "`#[cfg]` attribute in `where` clause is 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 57023ae89deaf..7d38ae7e9d00c 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -726,8 +726,9 @@ impl<'a> State<'a> { } pub fn print_where_predicate(&mut self, predicate: &ast::WherePredicate) { - let &ast::WherePredicate { ref kind, id, span: _ } = predicate; + let &ast::WherePredicate { ref attrs, ref kind, id, span: _ } = predicate; self.ann.pre(self, AnnNode::SubItem(id)); + 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/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs index b686a8cf935ca..0a7bc3f4d73fe 100644 --- a/compiler/rustc_builtin_macros/src/cfg_eval.rs +++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs @@ -80,6 +80,9 @@ fn flat_map_annotatable( vis.visit_crate(&mut krate); Some(Annotatable::Crate(krate)) } + Annotatable::WherePredicate(predicate) => { + vis.flat_map_where_predicate(predicate).pop().map(Annotatable::WherePredicate) + } } } @@ -114,6 +117,7 @@ fn has_cfg_or_cfg_attr(annotatable: &Annotatable) -> bool { Annotatable::FieldDef(field) => CfgFinder.visit_field_def(field), Annotatable::Variant(variant) => CfgFinder.visit_variant(variant), Annotatable::Crate(krate) => CfgFinder.visit_crate(krate), + Annotatable::WherePredicate(predicate) => CfgFinder.visit_where_predicate(predicate), }; res.is_break() } diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 91c0541a8cfd0..d4b91a6578ec5 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -761,8 +761,12 @@ 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, + }; where_clause.predicates.push(predicate); } } diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 7e4bc508e5c77..4eef247ec0259 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -53,6 +53,7 @@ pub enum Annotatable { FieldDef(ast::FieldDef), Variant(ast::Variant), Crate(ast::Crate), + WherePredicate(ast::WherePredicate), } impl Annotatable { @@ -71,6 +72,7 @@ impl Annotatable { Annotatable::FieldDef(sf) => sf.span, Annotatable::Variant(v) => v.span, Annotatable::Crate(c) => c.spans.inner_span, + Annotatable::WherePredicate(wp) => wp.span, } } @@ -89,6 +91,7 @@ impl Annotatable { Annotatable::FieldDef(sf) => sf.visit_attrs(f), Annotatable::Variant(v) => v.visit_attrs(f), Annotatable::Crate(c) => c.visit_attrs(f), + Annotatable::WherePredicate(wp) => wp.visit_attrs(f), } } @@ -107,6 +110,7 @@ impl Annotatable { Annotatable::FieldDef(sf) => visitor.visit_field_def(sf), Annotatable::Variant(v) => visitor.visit_variant(v), Annotatable::Crate(c) => visitor.visit_crate(c), + Annotatable::WherePredicate(wp) => visitor.visit_where_predicate(wp), } } @@ -127,7 +131,8 @@ impl Annotatable { | Annotatable::Param(..) | Annotatable::FieldDef(..) | Annotatable::Variant(..) - | Annotatable::Crate(..) => panic!("unexpected annotatable"), + | Annotatable::Crate(..) + | Annotatable::WherePredicate(..) => panic!("unexpected annotatable"), } } @@ -228,6 +233,13 @@ impl Annotatable { _ => panic!("expected krate"), } } + + pub fn expect_where_predicate(self) -> ast::WherePredicate { + match self { + Annotatable::WherePredicate(wp) => wp, + _ => panic!("expected where predicate"), + } + } } /// Result of an expansion that may need to be retried. @@ -449,6 +461,10 @@ pub trait MacResult { // Fn-like macros cannot produce a crate. unreachable!() } + + fn make_where_predicates(self: Box) -> Option> { + None + } } macro_rules! make_MacEager { diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 04ac7891023f5..99c82daa7a437 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -229,6 +229,12 @@ ast_fragments! { "variant"; many fn flat_map_variant; fn visit_variant(); fn make_variants; } Crate(ast::Crate) { "crate"; one fn visit_crate; fn visit_crate; fn make_crate; } + WherePredicate(SmallVec<[ast::WherePredicate; 1]>) { + "where predicate"; + many fn flat_map_where_predicate; + fn visit_where_predicate(); + fn make_where_predicates; + } } pub enum SupportsMacroExpansion { @@ -260,7 +266,8 @@ impl AstFragmentKind { | AstFragmentKind::GenericParams | AstFragmentKind::Params | AstFragmentKind::FieldDefs - | AstFragmentKind::Variants => SupportsMacroExpansion::No, + | AstFragmentKind::Variants + | AstFragmentKind::WherePredicate => SupportsMacroExpansion::No, } } @@ -318,6 +325,9 @@ impl AstFragmentKind { AstFragmentKind::Crate => { AstFragment::Crate(items.next().expect("expected exactly one crate").expect_crate()) } + AstFragmentKind::WherePredicate => AstFragment::WherePredicate( + items.map(Annotatable::expect_where_predicate).collect(), + ), AstFragmentKind::Pat | AstFragmentKind::Ty => { panic!("patterns and types aren't annotatable") } @@ -866,7 +876,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; @@ -1003,7 +1014,8 @@ pub fn parse_ast_fragment<'a>( | AstFragmentKind::GenericParams | AstFragmentKind::Params | AstFragmentKind::FieldDefs - | AstFragmentKind::Variants => panic!("unexpected AST fragment kind"), + | AstFragmentKind::Variants + | AstFragmentKind::WherePredicate => panic!("unexpected AST fragment kind"), }) } @@ -1587,6 +1599,19 @@ impl InvocationCollectorNode for ast::Crate { } } +impl InvocationCollectorNode for ast::WherePredicate { + const KIND: AstFragmentKind = AstFragmentKind::WherePredicate; + fn to_annotatable(self) -> Annotatable { + Annotatable::WherePredicate(self) + } + fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { + fragment.make_where_predicates() + } + fn walk_flat_map(self, visitor: &mut V) -> Self::OutputTy { + walk_flat_map_where_predicate(visitor, self) + } +} + impl InvocationCollectorNode for P { type OutputTy = P; const KIND: AstFragmentKind = AstFragmentKind::Ty; @@ -2179,6 +2204,13 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { self.visit_node(node) } + fn flat_map_where_predicate( + &mut self, + node: ast::WherePredicate, + ) -> SmallVec<[ast::WherePredicate; 1]> { + self.flat_map_node(node) + } + fn visit_expr(&mut self, node: &mut P) { // FIXME: Feature gating is performed inconsistently between `Expr` and `OptExpr`. if let Some(attr) = node.attrs.first() { diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index 610c69e9d21b4..014632a0513d0 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -187,6 +187,19 @@ pub(crate) fn placeholder( vis, is_placeholder: true, }]), + AstFragmentKind::WherePredicate => { + AstFragment::WherePredicate(smallvec![ast::WherePredicate { + attrs: Default::default(), + id, + span, + kind: ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate { + span, + bound_generic_params: Default::default(), + bounded_ty: ty(), + bounds: Default::default(), + }), + }]) + } } } diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 5f83c211b386b..dee580398cc3e 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -389,6 +389,8 @@ declare_features! ( (unstable, async_for_loop, "1.77.0", Some(118898)), /// Allows using C-variadics. (unstable, c_variadic, "1.34.0", Some(44930)), + /// Allows the use of `#[cfg]` in `where` clauses. + (unstable, cfg_attribute_in_where, "CURRENT_RUSTC_VERSION", Some(115590)), /// Allows the use of `#[cfg()]`. (unstable, cfg_boolean_literals, "1.83.0", Some(131204)), /// Allows the use of `#[cfg(overflow_checks)` to check if integer overflow behaviour. diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 1dedf11f7ad19..0a3d7f8600c8d 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -2161,6 +2161,7 @@ impl<'a> State<'a> { } fn print_where_predicate(&mut self, predicate: &hir::WherePredicate<'_>) { + self.print_outer_attributes(self.attrs(predicate.hir_id)); match *predicate.kind { hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate { bound_generic_params, diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index 6cf513f684112..319c34128a0be 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -5,7 +5,7 @@ use rustc_ast::{ }; use rustc_errors::{Applicability, PResult}; use rustc_span::Span; -use rustc_span::symbol::{Ident, kw}; +use rustc_span::symbol::{Ident, kw, sym}; use thin_vec::ThinVec; use super::{ForceCollect, Parser, Trailing, UsePreAttrPos}; @@ -341,34 +341,51 @@ impl<'a> Parser<'a> { loop { let where_sp = where_lo.to(self.prev_token.span); 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(&token::Colon)?; - let bounds = self.parse_lt_param_bounds(); - ast::WherePredicateKind::RegionPredicate(ast::WhereRegionPredicate { - span: pred_lo.to(self.prev_token.span), - lifetime, - bounds, - }) - } else if self.check_type() { - match self.parse_ty_where_predicate_or_recover_tuple_struct_body( - struct_, pred_lo, where_sp, - )? { - PredicateOrStructBody::Predicate(kind) => kind, - PredicateOrStructBody::StructBody(body) => { - tuple_struct_body = Some(body); - break; + let attrs = self.parse_outer_attributes()?; + let pred_kind_lo = self.token.span; + let predicate = + self.collect_tokens(None, attrs, ForceCollect::Yes, |this, attrs| { + for attr in &attrs { + self.psess.gated_spans.gate(sym::cfg_attribute_in_where, 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(&token::Colon)?; + let bounds = this.parse_lt_param_bounds(); + Some(ast::WherePredicateKind::RegionPredicate(ast::WhereRegionPredicate { + span: pred_kind_lo.to(this.prev_token.span), + lifetime, + bounds, + })) + } else if this.check_type() { + match this.parse_ty_where_predicate_or_recover_tuple_struct_body( + struct_, + pred_kind_lo, + where_sp, + )? { + PredicateOrStructBody::Predicate(kind) => Some(kind), + PredicateOrStructBody::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), + }); + 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(&token::Comma); @@ -376,7 +393,7 @@ impl<'a> Parser<'a> { if self.eat_keyword_noexpect(kw::Where) { self.dcx().emit_err(MultipleWhereClauses { span: self.token.span, - previous: pred_lo, + previous: pred_kind_lo, between: prev_token.shrink_to_hi().to(self.prev_token.span), }); } else if !ate_comma { diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 6f0bcf5c3f05a..a056f4258c79e 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -766,6 +766,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 = + attributes in `where` clauses are not supported + .help = only `#[cfg]` is supported in `where` clauses + 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 21467c34ef02a..360fb8877e113 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -2404,6 +2404,28 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> { intravisit::walk_item(self, item) } + fn visit_where_predicate(&mut self, where_predicate: &'tcx hir::WherePredicate<'tcx>) { + const ATTRS_ALLOWED: &[Symbol] = &[sym::cfg]; + 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::>(); + 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 70c92f0144cf7..92bf24295b4b9 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1839,3 +1839,11 @@ pub(crate) struct AttrCrateLevelOnlySugg { #[primary_span] pub attr: Span, } + +#[derive(Diagnostic)] +#[diag(passes_unsupported_attributes_in_where)] +#[help] +pub(crate) struct UnsupportedAttributesInWhere { + #[primary_span] + pub span: MultiSpan, +} diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 82cfbd28fff15..68f7b5672e6d2 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -539,6 +539,7 @@ symbols! { cfg_accessible, cfg_attr, cfg_attr_multi, + cfg_attribute_in_where, cfg_autodiff_fallback, cfg_boolean_literals, cfg_doctest, diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index c90f4a6ebfe63..5bad58ca2354a 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -662,19 +662,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/types.rs b/src/tools/rustfmt/src/types.rs index 07103c5ea699f..b79a62c24804f 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -462,8 +462,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.kind.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: 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 0000000000000..11f495b162995 --- /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 +where + #[cfg = a_very_long_attribute_name] + T: TraitA, + #[cfg = another_very_long_attribute_name] + T: TraitB, +{ + type B + 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(&self) + where + /// line doc comment before the attribute + U: TraitA, + /** line doc block comment before the attribute */ + U: TraitB; +} + +impl A for T +where + #[doc = "line doc before the attribute"] + T: TraitA, + /** short doc */ + T: TraitB, +{ + type B + = () + where + #[doc = "short"] U: TraitA, + #[doc = "short"] + #[cfg = a] + U: TraitB; + + fn foo(&self) + where + #[cfg = a] + #[cfg = b] + U: TraitA, + /// line doc + #[cfg = c] + U: TraitB, + { + } +} + +struct C +where + #[cfg = a] T: TraitA, + #[cfg = b] T: TraitB, +{ + _t: PhantomData, +} + +union D +where + #[cfg = a] T: TraitA, + #[cfg = b] T: TraitB, +{ + _t: PhantomData, +} + +enum E +where + #[cfg = a] T: TraitA, + #[cfg = b] T: TraitB, +{ + E(PhantomData), +} + +#[allow(type_alias_bounds)] +type F +where + #[cfg = a] T: TraitA, + #[cfg = b] T: TraitB, += T; + +impl C +where + #[cfg = a] T: TraitA, + #[cfg = b] T: TraitB, +{ + fn new() + where + #[cfg = a] U: TraitA, + #[cfg = b] U: TraitB, + { + } +} + +fn foo() +where + #[cfg = a] T: TraitA, + #[cfg = b] T: TraitB, +{ +} diff --git a/tests/ui/feature-gates/feature-gate-cfg_attribute_in_where.a.stderr b/tests/ui/feature-gates/feature-gate-cfg_attribute_in_where.a.stderr new file mode 100644 index 0000000000000..b6fb7f530bd4a --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-cfg_attribute_in_where.a.stderr @@ -0,0 +1,413 @@ +error[E0658]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:20:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:21:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:22:5 + | +LL | #[cfg(all())] T: Defined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:23:5 + | +LL | #[cfg(any())] T: Undefined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:27:9 + | +LL | #[cfg(a)] U: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:28:9 + | +LL | #[cfg(b)] U: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:29:9 + | +LL | #[cfg(all())] T: Defined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:30:9 + | +LL | #[cfg(any())] T: Undefined; + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:34:9 + | +LL | #[cfg(a)] U: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:35:9 + | +LL | #[cfg(b)] U: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:36:9 + | +LL | #[cfg(all())] T: Defined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:37:9 + | +LL | #[cfg(any())] T: Undefined; + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:42:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:43:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:44:5 + | +LL | #[cfg(all())] T: Defined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:45:5 + | +LL | #[cfg(any())] T: Undefined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:48:9 + | +LL | #[cfg(a)] U: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:49:9 + | +LL | #[cfg(b)] U: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:50:9 + | +LL | #[cfg(any())] T: Undefined; + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:54:9 + | +LL | #[cfg(a)] U: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:55:9 + | +LL | #[cfg(b)] U: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:56:9 + | +LL | #[cfg(any())] T: Undefined {} + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:61:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:62:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:63:5 + | +LL | #[cfg(all())] T: Defined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:64:5 + | +LL | #[cfg(any())] T: Undefined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:71:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:72:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:73:5 + | +LL | #[cfg(any())] T: Undefined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:81:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:82:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:83:5 + | +LL | #[cfg(all())] T: Defined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:84:5 + | +LL | #[cfg(any())] T: Undefined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:90:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:91:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:92:5 + | +LL | #[cfg(all())] T: Defined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:93:5 + | +LL | #[cfg(any())] T: Undefined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:96:9 + | +LL | #[cfg(a)] U: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:97:9 + | +LL | #[cfg(b)] U: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:98:9 + | +LL | #[cfg(all())] T: Defined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:99:9 + | +LL | #[cfg(any())] T: Undefined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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 41 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-cfg_attribute_in_where.b.stderr b/tests/ui/feature-gates/feature-gate-cfg_attribute_in_where.b.stderr new file mode 100644 index 0000000000000..b6fb7f530bd4a --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-cfg_attribute_in_where.b.stderr @@ -0,0 +1,413 @@ +error[E0658]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:20:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:21:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:22:5 + | +LL | #[cfg(all())] T: Defined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:23:5 + | +LL | #[cfg(any())] T: Undefined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:27:9 + | +LL | #[cfg(a)] U: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:28:9 + | +LL | #[cfg(b)] U: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:29:9 + | +LL | #[cfg(all())] T: Defined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:30:9 + | +LL | #[cfg(any())] T: Undefined; + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:34:9 + | +LL | #[cfg(a)] U: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:35:9 + | +LL | #[cfg(b)] U: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:36:9 + | +LL | #[cfg(all())] T: Defined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:37:9 + | +LL | #[cfg(any())] T: Undefined; + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:42:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:43:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:44:5 + | +LL | #[cfg(all())] T: Defined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:45:5 + | +LL | #[cfg(any())] T: Undefined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:48:9 + | +LL | #[cfg(a)] U: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:49:9 + | +LL | #[cfg(b)] U: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:50:9 + | +LL | #[cfg(any())] T: Undefined; + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:54:9 + | +LL | #[cfg(a)] U: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:55:9 + | +LL | #[cfg(b)] U: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:56:9 + | +LL | #[cfg(any())] T: Undefined {} + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:61:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:62:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:63:5 + | +LL | #[cfg(all())] T: Defined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:64:5 + | +LL | #[cfg(any())] T: Undefined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:71:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:72:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:73:5 + | +LL | #[cfg(any())] T: Undefined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:81:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:82:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:83:5 + | +LL | #[cfg(all())] T: Defined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:84:5 + | +LL | #[cfg(any())] T: Undefined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:90:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:91:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:92:5 + | +LL | #[cfg(all())] T: Defined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:93:5 + | +LL | #[cfg(any())] T: Undefined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:96:9 + | +LL | #[cfg(a)] U: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:97:9 + | +LL | #[cfg(b)] U: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:98:9 + | +LL | #[cfg(all())] T: Defined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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]: `#[cfg]` attribute in `where` clause is unstable + --> $DIR/feature-gate-cfg_attribute_in_where.rs:99:9 + | +LL | #[cfg(any())] T: Undefined, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(cfg_attribute_in_where)]` 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 41 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-cfg_attribute_in_where.rs b/tests/ui/feature-gates/feature-gate-cfg_attribute_in_where.rs new file mode 100644 index 0000000000000..525d7af7c2c65 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-cfg_attribute_in_where.rs @@ -0,0 +1,101 @@ +//@ revisions: a b + +#![crate_type = "lib"] +use std::marker::PhantomData; + +#[cfg(a)] +trait TraitA {} + +#[cfg(b)] +trait TraitB {} + +#[cfg(all())] +trait Defined {} + +#[cfg(any())] +trait Undefined {} + +trait A +where + #[cfg(a)] T: TraitA, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(b)] T: TraitB, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(all())] T: Defined, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(any())] T: Undefined, //~ `#[cfg]` attribute in `where` clause is unstable +{ + type B + where + #[cfg(a)] U: TraitA, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(b)] U: TraitB, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(all())] T: Defined, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(any())] T: Undefined; //~ `#[cfg]` attribute in `where` clause is unstable + + fn foo(&self) + where + #[cfg(a)] U: TraitA, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(b)] U: TraitB, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(all())] T: Defined, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(any())] T: Undefined; //~ `#[cfg]` attribute in `where` clause is unstable +} + +impl A for T +where + #[cfg(a)] T: TraitA, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(b)] T: TraitB, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(all())] T: Defined, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(any())] T: Undefined, //~ `#[cfg]` attribute in `where` clause is unstable +{ + type B = () where + #[cfg(a)] U: TraitA, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(b)] U: TraitB, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(any())] T: Undefined; //~ `#[cfg]` attribute in `where` clause is unstable + + fn foo(&self) + where + #[cfg(a)] U: TraitA, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(b)] U: TraitB, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(any())] T: Undefined {} //~ `#[cfg]` attribute in `where` clause is unstable +} + +struct C +where + #[cfg(a)] T: TraitA, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(b)] T: TraitB, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(all())] T: Defined, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(any())] T: Undefined, //~ `#[cfg]` attribute in `where` clause is unstable +{ + _t: PhantomData, +} + +union D +where + #[cfg(a)] T: TraitA, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(b)] T: TraitB, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(any())] T: Undefined, //~ `#[cfg]` attribute in `where` clause is unstable +{ + + _t: PhantomData, +} + +enum E +where + #[cfg(a)] T: TraitA, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(b)] T: TraitB, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(all())] T: Defined, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(any())] T: Undefined, //~ `#[cfg]` attribute in `where` clause is unstable +{ + E(PhantomData), +} + +impl C where + #[cfg(a)] T: TraitA, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(b)] T: TraitB, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(all())] T: Defined, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(any())] T: Undefined, //~ `#[cfg]` attribute in `where` clause is unstable +{ + fn new() where + #[cfg(a)] U: TraitA, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(b)] U: TraitB, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(all())] T: Defined, //~ `#[cfg]` attribute in `where` clause is unstable + #[cfg(any())] T: Undefined, //~ `#[cfg]` attribute in `where` clause is unstable + {} +} diff --git a/tests/ui/parser/bounds-lifetime-where.rs b/tests/ui/parser/bounds-lifetime-where.rs index 7ff75233d3a8e..730be7139bec8 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 9dd963afc7963..5aadb5fff320b 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 196a46d7ea54b..6245f81d533be 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 - | ^^ 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/stats/hir-stats.stderr b/tests/ui/stats/hir-stats.stderr index 2fa03266d75a2..16e1a901b0b40 100644 --- a/tests/ui/stats/hir-stats.stderr +++ b/tests/ui/stats/hir-stats.stderr @@ -8,9 +8,9 @@ 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 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 WherePredicate 80 ( 1.2%) 1 80 +ast-stats-1 - BoundPredicate 80 ( 1.2%) 1 ast-stats-1 ForeignItem 88 ( 1.3%) 1 88 ast-stats-1 - Fn 88 ( 1.3%) 1 ast-stats-1 Arm 96 ( 1.4%) 2 48 @@ -33,14 +33,14 @@ ast-stats-1 Pat 504 ( 7.6%) 7 72 ast-stats-1 - Struct 72 ( 1.1%) 1 ast-stats-1 - Wild 72 ( 1.1%) 1 ast-stats-1 - Ident 360 ( 5.4%) 5 -ast-stats-1 Expr 576 ( 8.7%) 8 72 +ast-stats-1 Expr 576 ( 8.6%) 8 72 ast-stats-1 - Path 72 ( 1.1%) 1 ast-stats-1 - Match 72 ( 1.1%) 1 ast-stats-1 - Struct 72 ( 1.1%) 1 ast-stats-1 - Lit 144 ( 2.2%) 2 ast-stats-1 - Block 216 ( 3.2%) 3 ast-stats-1 PathSegment 744 (11.2%) 31 24 -ast-stats-1 Ty 896 (13.5%) 14 64 +ast-stats-1 Ty 896 (13.4%) 14 64 ast-stats-1 - Ref 64 ( 1.0%) 1 ast-stats-1 - Ptr 64 ( 1.0%) 1 ast-stats-1 - ImplicitSelf 128 ( 1.9%) 2 @@ -53,7 +53,7 @@ ast-stats-1 - Enum 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_656 +ast-stats-1 Total 6_664 ast-stats-1 ast-stats-2 POST EXPANSION AST STATS ast-stats-2 Name Accumulated Size Count Item Size @@ -62,9 +62,9 @@ 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 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 WherePredicate 80 ( 1.1%) 1 80 +ast-stats-2 - BoundPredicate 80 ( 1.1%) 1 ast-stats-2 ForeignItem 88 ( 1.2%) 1 88 ast-stats-2 - Fn 88 ( 1.2%) 1 ast-stats-2 Arm 96 ( 1.3%) 2 48 @@ -113,7 +113,7 @@ ast-stats-2 - ForeignMod 136 ( 1.9%) 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_304 +ast-stats-2 Total 7_312 ast-stats-2 hir-stats HIR STATS hir-stats Name Accumulated Size Count Item Size diff --git a/tests/ui/where-clauses/cfg_attribute.rs b/tests/ui/where-clauses/cfg_attribute.rs new file mode 100644 index 0000000000000..8815edc36c5cc --- /dev/null +++ b/tests/ui/where-clauses/cfg_attribute.rs @@ -0,0 +1,91 @@ +//@ revisions: a b +//@ check-pass + +#![crate_type = "lib"] +#![feature(cfg_attribute_in_where)] +use std::marker::PhantomData; + +#[cfg(a)] +trait TraitA {} + +#[cfg(b)] +trait TraitB {} + +trait A +where + #[cfg(a)] T: TraitA, + #[cfg(b)] T: TraitB, +{ + type B + where + #[cfg(a)] U: TraitA, + #[cfg(b)] U: TraitB; + + fn foo(&self) + where + #[cfg(a)] U: TraitA, + #[cfg(b)] U: TraitB; +} + +impl A for T +where + #[cfg(a)] T: TraitA, + #[cfg(b)] T: TraitB, +{ + type B = () where + #[cfg(a)] U: TraitA, + #[cfg(b)] U: TraitB; + + fn foo(&self) + where + #[cfg(a)] U: TraitA, + #[cfg(b)] U: TraitB, {} +} + +struct C +where + #[cfg(a)] T: TraitA, + #[cfg(b)] T: TraitB, +{ + _t: PhantomData, +} + +union D +where + #[cfg(a)] T: TraitA, + #[cfg(b)] T: TraitB, +{ + + _t: PhantomData, +} + +enum E +where + #[cfg(a)] T: TraitA, + #[cfg(b)] T: TraitB, +{ + E(PhantomData), +} + +#[allow(type_alias_bounds)] +type F +where + #[cfg(a)] T: TraitA, + #[cfg(b)] T: TraitB = T; + +impl C where + #[cfg(a)] T: TraitA, + #[cfg(b)] T: TraitB, +{ + fn new() where + #[cfg(a)] U: TraitA, + #[cfg(b)] U: TraitB, + {} +} + +fn foo() +where + #[cfg(a)] T: TraitA, + #[cfg(b)] T: TraitB, +{ +} diff --git a/tests/ui/where-clauses/unsupported_attribute.rs b/tests/ui/where-clauses/unsupported_attribute.rs new file mode 100644 index 0000000000000..564fc5c73340c --- /dev/null +++ b/tests/ui/where-clauses/unsupported_attribute.rs @@ -0,0 +1,28 @@ +#![crate_type = "lib"] +#![feature(cfg_attribute_in_where)] + +trait Trait {} + +fn foo<'a, T>() +where + #[doc = "doc"] T: Trait, //~ ERROR attributes in `where` clauses are not supported + #[doc = "doc"] 'a: 'static, //~ ERROR attributes in `where` clauses are not supported + #[ignore] T: Trait, //~ ERROR attributes in `where` clauses are not supported + #[ignore] 'a: 'static, //~ ERROR attributes in `where` clauses are not supported + #[should_panic] T: Trait, //~ ERROR attributes in `where` clauses are not supported + #[should_panic] 'a: 'static, //~ ERROR attributes in `where` clauses are not supported + #[macro_use] T: Trait, //~ ERROR attributes in `where` clauses are not supported + #[macro_use] 'a: 'static, //~ ERROR attributes in `where` clauses are not supported + #[allow(unused)] T: Trait, //~ ERROR attributes in `where` clauses are not supported + #[allow(unused)] 'a: 'static, //~ ERROR attributes in `where` clauses are not supported + #[warn(unused)] T: Trait, //~ ERROR attributes in `where` clauses are not supported + #[warn(unused)] 'a: 'static, //~ ERROR attributes in `where` clauses are not supported + #[deny(unused)] T: Trait, //~ ERROR attributes in `where` clauses are not supported + #[deny(unused)] 'a: 'static, //~ ERROR attributes in `where` clauses are not supported + #[forbid(unused)] T: Trait, //~ ERROR attributes in `where` clauses are not supported + #[forbid(unused)] 'a: 'static, //~ ERROR attributes in `where` clauses are not supported + #[deprecated] T: Trait, //~ ERROR attributes in `where` clauses are not supported + #[deprecated] 'a: 'static, //~ ERROR attributes in `where` clauses are not supported + #[automatically_derived] T: Trait, //~ ERROR attributes in `where` clauses are not supported + #[automatically_derived] 'a: 'static, //~ ERROR attributes in `where` clauses are not supported +{} diff --git a/tests/ui/where-clauses/unsupported_attribute.stderr b/tests/ui/where-clauses/unsupported_attribute.stderr new file mode 100644 index 0000000000000..7d0aaf4f8b2e8 --- /dev/null +++ b/tests/ui/where-clauses/unsupported_attribute.stderr @@ -0,0 +1,162 @@ +error: attributes in `where` clauses are not supported + --> $DIR/unsupported_attribute.rs:8:5 + | +LL | #[doc = "doc"] T: Trait, + | ^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` is supported in `where` clauses + +error: attributes in `where` clauses are not supported + --> $DIR/unsupported_attribute.rs:9:5 + | +LL | #[doc = "doc"] 'a: 'static, + | ^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` is supported in `where` clauses + +error: attributes in `where` clauses are not supported + --> $DIR/unsupported_attribute.rs:10:5 + | +LL | #[ignore] T: Trait, + | ^^^^^^^^^ + | + = help: only `#[cfg]` is supported in `where` clauses + +error: attributes in `where` clauses are not supported + --> $DIR/unsupported_attribute.rs:11:5 + | +LL | #[ignore] 'a: 'static, + | ^^^^^^^^^ + | + = help: only `#[cfg]` is supported in `where` clauses + +error: attributes in `where` clauses are not supported + --> $DIR/unsupported_attribute.rs:12:5 + | +LL | #[should_panic] T: Trait, + | ^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` is supported in `where` clauses + +error: attributes in `where` clauses are not supported + --> $DIR/unsupported_attribute.rs:13:5 + | +LL | #[should_panic] 'a: 'static, + | ^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` is supported in `where` clauses + +error: attributes in `where` clauses are not supported + --> $DIR/unsupported_attribute.rs:14:5 + | +LL | #[macro_use] T: Trait, + | ^^^^^^^^^^^^ + | + = help: only `#[cfg]` is supported in `where` clauses + +error: attributes in `where` clauses are not supported + --> $DIR/unsupported_attribute.rs:15:5 + | +LL | #[macro_use] 'a: 'static, + | ^^^^^^^^^^^^ + | + = help: only `#[cfg]` is supported in `where` clauses + +error: attributes in `where` clauses are not supported + --> $DIR/unsupported_attribute.rs:16:5 + | +LL | #[allow(unused)] T: Trait, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` is supported in `where` clauses + +error: attributes in `where` clauses are not supported + --> $DIR/unsupported_attribute.rs:17:5 + | +LL | #[allow(unused)] 'a: 'static, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` is supported in `where` clauses + +error: attributes in `where` clauses are not supported + --> $DIR/unsupported_attribute.rs:18:5 + | +LL | #[warn(unused)] T: Trait, + | ^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` is supported in `where` clauses + +error: attributes in `where` clauses are not supported + --> $DIR/unsupported_attribute.rs:19:5 + | +LL | #[warn(unused)] 'a: 'static, + | ^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` is supported in `where` clauses + +error: attributes in `where` clauses are not supported + --> $DIR/unsupported_attribute.rs:20:5 + | +LL | #[deny(unused)] T: Trait, + | ^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` is supported in `where` clauses + +error: attributes in `where` clauses are not supported + --> $DIR/unsupported_attribute.rs:21:5 + | +LL | #[deny(unused)] 'a: 'static, + | ^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` is supported in `where` clauses + +error: attributes in `where` clauses are not supported + --> $DIR/unsupported_attribute.rs:22:5 + | +LL | #[forbid(unused)] T: Trait, + | ^^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` is supported in `where` clauses + +error: attributes in `where` clauses are not supported + --> $DIR/unsupported_attribute.rs:23:5 + | +LL | #[forbid(unused)] 'a: 'static, + | ^^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` is supported in `where` clauses + +error: attributes in `where` clauses are not supported + --> $DIR/unsupported_attribute.rs:24:5 + | +LL | #[deprecated] T: Trait, + | ^^^^^^^^^^^^^ + | + = help: only `#[cfg]` is supported in `where` clauses + +error: attributes in `where` clauses are not supported + --> $DIR/unsupported_attribute.rs:25:5 + | +LL | #[deprecated] 'a: 'static, + | ^^^^^^^^^^^^^ + | + = help: only `#[cfg]` is supported in `where` clauses + +error: attributes in `where` clauses are not supported + --> $DIR/unsupported_attribute.rs:26:5 + | +LL | #[automatically_derived] T: Trait, + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` is supported in `where` clauses + +error: attributes in `where` clauses are not supported + --> $DIR/unsupported_attribute.rs:27:5 + | +LL | #[automatically_derived] 'a: 'static, + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` is supported in `where` clauses + +error: aborting due to 20 previous errors +