From ba719b986232ec736a8ab96c57ecf82a6606acdb Mon Sep 17 00:00:00 2001 From: stuuupidcat Date: Wed, 5 Mar 2025 06:15:17 +0000 Subject: [PATCH] Fix split calculation in type alias where clauses --- compiler/rustc_ast/src/ast.rs | 4 +- compiler/rustc_ast/src/mut_visit.rs | 2 +- .../rustc_ast_passes/src/ast_validation.rs | 4 +- .../rustc_ast_pretty/src/pprust/state/item.rs | 2 +- compiler/rustc_parse/src/parser/item.rs | 7 +- src/tools/rustfmt/src/items.rs | 2 +- .../where-clauses/cfg-attr-issue-138010-1.rs | 30 ++++++++ .../cfg-attr-issue-138010-1.stderr | 70 +++++++++++++++++++ .../where-clauses/cfg-attr-issue-138010-2.rs | 33 +++++++++ .../cfg-attr-issue-138010-2.stderr | 39 +++++++++++ 10 files changed, 187 insertions(+), 6 deletions(-) create mode 100644 tests/ui/where-clauses/cfg-attr-issue-138010-1.rs create mode 100644 tests/ui/where-clauses/cfg-attr-issue-138010-1.stderr create mode 100644 tests/ui/where-clauses/cfg-attr-issue-138010-2.rs create mode 100644 tests/ui/where-clauses/cfg-attr-issue-138010-2.stderr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 002435b2d0327..d7ca4ac100648 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -3429,7 +3429,9 @@ pub struct TyAliasWhereClauses { /// The index in `TyAlias.generics.where_clause.predicates` that would split /// into predicates from the where clause before the equals sign and the ones /// from the where clause after the equals sign. - pub split: usize, + pub before_count: usize, + /// The count of the clauses that appear before the equals sign and have attrbutes. + pub before_with_attr_count: usize, } #[derive(Clone, Encodable, Decodable, Debug)] diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index ee894db7b966b..f13e0e76b2a7b 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1091,7 +1091,7 @@ fn walk_generics(vis: &mut T, generics: &mut Generics) { } fn walk_ty_alias_where_clauses(vis: &mut T, tawcs: &mut TyAliasWhereClauses) { - let TyAliasWhereClauses { before, after, split: _ } = tawcs; + let TyAliasWhereClauses { before, after, before_count: _, before_with_attr_count: _ } = tawcs; let TyAliasWhereClause { has_where_token: _, span: span_before } = before; let TyAliasWhereClause { has_where_token: _, span: span_after } = after; vis.visit_span(span_before); diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index f9f4035cb22f0..d832e4b45e748 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -136,8 +136,10 @@ impl<'a> AstValidator<'a> { return Ok(()); } + let split = + ty_alias.where_clauses.before_count - ty_alias.where_clauses.before_with_attr_count; let (before_predicates, after_predicates) = - ty_alias.generics.where_clause.predicates.split_at(ty_alias.where_clauses.split); + ty_alias.generics.where_clause.predicates.split_at(split); let span = ty_alias.where_clauses.before.span; let sugg = if !before_predicates.is_empty() || !ty_alias.where_clauses.after.has_where_token diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index ced0cbd2fef68..ebaaf6cbcec1e 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -125,7 +125,7 @@ impl<'a> State<'a> { defaultness: ast::Defaultness, ) { let (before_predicates, after_predicates) = - generics.where_clause.predicates.split_at(where_clauses.split); + generics.where_clause.predicates.split_at(where_clauses.before_count); self.head(""); self.print_visibility(vis); self.print_defaultness(defaultness); diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 0b9350c71992a..da18f57f63bb4 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1024,7 +1024,12 @@ impl<'a> Parser<'a> { has_where_token: after_where_clause.has_where_token, span: after_where_clause.span, }, - split: before_where_clause.predicates.len(), + before_count: before_where_clause.predicates.len(), + before_with_attr_count: before_where_clause + .predicates + .iter() + .filter(|p| !p.attrs.is_empty()) + .count(), }; let mut predicates = before_where_clause.predicates; predicates.extend(after_where_clause.predicates); diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs index 3fb3284e3d7fd..1f03781b37eaf 100644 --- a/src/tools/rustfmt/src/items.rs +++ b/src/tools/rustfmt/src/items.rs @@ -1768,7 +1768,7 @@ fn rewrite_ty( let (before_where_predicates, after_where_predicates) = generics .where_clause .predicates - .split_at(where_clauses.split); + .split_at(where_clauses.before_count); result.push_str(&format!("{}type ", format_visibility(context, vis))); let ident_str = rewrite_ident(context, ident); diff --git a/tests/ui/where-clauses/cfg-attr-issue-138010-1.rs b/tests/ui/where-clauses/cfg-attr-issue-138010-1.rs new file mode 100644 index 0000000000000..40897a724d577 --- /dev/null +++ b/tests/ui/where-clauses/cfg-attr-issue-138010-1.rs @@ -0,0 +1,30 @@ +#![feature(lazy_type_alias)] +//~^ WARNING: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] + +trait TraitA {} +trait TraitB {} + +fn this(_x: &()) {} + +fn needs_copy() { + type F + where + //~^ ERROR: where clauses are not allowed before the type for type aliases + #[cfg(a)] + //~^ ERROR: attributes in `where` clause are unstable + //~| WARNING: unexpected `cfg` condition name: `a` + T: TraitA, + #[cfg(b)] + //~^ ERROR: attributes in `where` clause are unstable + //~| WARNING: unexpected `cfg` condition name: `b` + T: TraitB, + ():, + ():, + = T; + let x: () = (); + this(&x); +} + +fn main() { + needs_copy::<()>(); +} diff --git a/tests/ui/where-clauses/cfg-attr-issue-138010-1.stderr b/tests/ui/where-clauses/cfg-attr-issue-138010-1.stderr new file mode 100644 index 0000000000000..b079320dd2983 --- /dev/null +++ b/tests/ui/where-clauses/cfg-attr-issue-138010-1.stderr @@ -0,0 +1,70 @@ +error: where clauses are not allowed before the type for type aliases + --> $DIR/cfg-attr-issue-138010-1.rs:11:5 + | +LL | / where +LL | | +LL | | #[cfg(a)] +... | +LL | | ():, +LL | | ():, + | |____________^ + | + = note: see issue #89122 for more information +help: move it to the end of the type declaration + | +LL ~ +LL ~ = T where ():, ():; + | + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/cfg-attr-issue-138010-1.rs:13:9 + | +LL | #[cfg(a)] + | ^^^^^^^^^ + | + = note: see issue #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/cfg-attr-issue-138010-1.rs:17:9 + | +LL | #[cfg(b)] + | ^^^^^^^^^ + | + = note: see issue #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 + +warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/cfg-attr-issue-138010-1.rs:1:12 + | +LL | #![feature(lazy_type_alias)] + | ^^^^^^^^^^^^^^^ + | + = note: see issue #112792 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: unexpected `cfg` condition name: `a` + --> $DIR/cfg-attr-issue-138010-1.rs:13:15 + | +LL | #[cfg(a)] + | ^ help: found config with similar value: `target_feature = "a"` + | + = help: expected names are: `FALSE` and `test` and 31 more + = help: to expect this configuration use `--check-cfg=cfg(a)` + = note: see for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: unexpected `cfg` condition name: `b` + --> $DIR/cfg-attr-issue-138010-1.rs:17:15 + | +LL | #[cfg(b)] + | ^ + | + = help: to expect this configuration use `--check-cfg=cfg(b)` + = note: see for more information about checking conditional configuration + +error: aborting due to 3 previous errors; 3 warnings emitted + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/where-clauses/cfg-attr-issue-138010-2.rs b/tests/ui/where-clauses/cfg-attr-issue-138010-2.rs new file mode 100644 index 0000000000000..623d54b7eeb77 --- /dev/null +++ b/tests/ui/where-clauses/cfg-attr-issue-138010-2.rs @@ -0,0 +1,33 @@ +#![feature(where_clause_attrs, cfg_boolean_literals, lazy_type_alias)] +#![expect(incomplete_features)] + +struct Foo; +trait Trait {} + +impl Trait for Foo {} + +type MixedWhereBounds1 +where //~ ERROR: where clauses are not allowed before the type for type aliases + #[cfg(true)] + Foo: Trait, += Foo +where + (): Sized; + +type MixedWhereBounds2 +where //~ ERROR: where clauses are not allowed before the type for type aliases + #[cfg(false)] + Foo: Trait, += Foo +where + (): Sized; + +type MixedWhereBounds3 +where +//~^ ERROR: where clauses are not allowed before the type for type aliases + Foo: Trait, += Foo +where + (): Sized; + +fn main() {} diff --git a/tests/ui/where-clauses/cfg-attr-issue-138010-2.stderr b/tests/ui/where-clauses/cfg-attr-issue-138010-2.stderr new file mode 100644 index 0000000000000..df64fe03db693 --- /dev/null +++ b/tests/ui/where-clauses/cfg-attr-issue-138010-2.stderr @@ -0,0 +1,39 @@ +error: where clauses are not allowed before the type for type aliases + --> $DIR/cfg-attr-issue-138010-2.rs:10:1 + | +LL | / where +LL | | #[cfg(true)] +LL | | Foo: Trait, + | |_______________^ help: remove this `where` + | + = note: see issue #89122 for more information + +error: where clauses are not allowed before the type for type aliases + --> $DIR/cfg-attr-issue-138010-2.rs:18:1 + | +LL | / where +LL | | #[cfg(false)] +LL | | Foo: Trait, + | |_______________^ help: remove this `where` + | + = note: see issue #89122 for more information + +error: where clauses are not allowed before the type for type aliases + --> $DIR/cfg-attr-issue-138010-2.rs:26:1 + | +LL | / where +LL | | +LL | | Foo: Trait, + | |_______________^ + | + = note: see issue #89122 for more information +help: move it to the end of the type declaration + | +LL + +LL | = Foo +LL | where +LL ~ (): Sized, Foo: Trait; + | + +error: aborting due to 3 previous errors +