diff options
| author | Matthias Krüger <476013+matthiaskrgr@users.noreply.github.com> | 2025-03-03 10:40:56 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-03 10:40:56 +0100 |
| commit | 2344a34241e2cf08e6285ddf7755b70bfa306e5a (patch) | |
| tree | 5e72f03cef42d18af3990ac2e88a906d730d70c2 /src | |
| parent | 81d8edc2000aa38b08ad09fce22d90f1990b6459 (diff) | |
| parent | 42f51d4fd42c95e0c51c3f8742d63db0548cd5a0 (diff) | |
| download | rust-2344a34241e2cf08e6285ddf7755b70bfa306e5a.tar.gz rust-2344a34241e2cf08e6285ddf7755b70bfa306e5a.zip | |
Rollup merge of #132388 - frank-king:feature/where-cfg, r=petrochenkov
Implement `#[cfg]` in `where` clauses This PR implements #115590, which supports `#[cfg]` attributes in `where` clauses. The biggest change is, that it adds `AttrsVec` and `NodeId` to the `ast::WherePredicate` and `HirId` to the `hir::WherePredicate`.
Diffstat (limited to 'src')
| -rw-r--r-- | src/tools/clippy/clippy_utils/src/ast_utils/mod.rs | 27 | ||||
| -rw-r--r-- | src/tools/rustfmt/src/spanned.rs | 7 | ||||
| -rw-r--r-- | src/tools/rustfmt/src/types.rs | 35 | ||||
| -rw-r--r-- | src/tools/rustfmt/tests/target/cfg_attribute_in_where.rs | 116 |
4 files changed, 165 insertions, 20 deletions
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, +{ +} |
