Rollup merge of #113560 - fmease:assoc-tys-in-traits-depr-wc-loc, r=compiler-errors

Lint against misplaced where-clauses on associated types in traits

Extends the scope of the lint `deprecated_where_clause_location` (#89122) from associated types in impls to associated types in any location (impl or trait). This is only relevant for `#![feature(associated_type_defaults)]`. Previously we didn't warn on the following code for example:

```rs
#![feature(associated_type_defaults)]
trait Trait { type Assoc where u32: Copy = (); }
```

Personally I would've preferred to emit a *hard* error here instead of a lint warning since the feature is unstable but unfortunately we are constrained by back compat as associated type defaults won't necessarily trigger the feature-gate error if they are inside of a macro call (since they use a post-expansion feature-gate due to historical reasons, see also #66004).

I've renamed and moved related preexisting tests: 1. They test AST validation passes not the parser & thus shouldn't live in `parser/` (historical reasons?). 2. One test file was named after type aliases even though it tests assoc tys.

`@rustbot` label A-lint
This commit is contained in:
Matthias Krüger 2023-07-11 17:46:20 +02:00 committed by GitHub
commit 4f5ef52c37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 81 additions and 21 deletions

View File

@ -1300,14 +1300,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
});
}
}
AssocItemKind::Type(box TyAlias {
generics,
where_clauses,
where_predicates_split,
bounds,
ty,
..
}) => {
AssocItemKind::Type(box TyAlias { bounds, ty, .. }) => {
if ty.is_none() {
self.session.emit_err(errors::AssocTypeWithoutBody {
span: item.span,
@ -1315,18 +1308,26 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
});
}
self.check_type_no_bounds(bounds, "`impl`s");
if ty.is_some() {
self.check_gat_where(
item.id,
generics.where_clause.predicates.split_at(*where_predicates_split).0,
*where_clauses,
);
}
}
_ => {}
}
}
if let AssocItemKind::Type(box TyAlias {
generics,
where_clauses,
where_predicates_split,
ty: Some(_),
..
}) = &item.kind
{
self.check_gat_where(
item.id,
generics.where_clause.predicates.split_at(*where_predicates_split).0,
*where_clauses,
);
}
if ctxt == AssocCtxt::Trait || self.in_trait_impl {
self.visibility_not_permitted(&item.vis, errors::VisibilityNotPermittedNote::TraitImpl);
if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind {

View File

@ -4084,7 +4084,7 @@ declare_lint! {
///
/// ### Explanation
///
/// The preferred location for where clauses on associated types in impls
/// The preferred location for where clauses on associated types
/// is after the type. However, for most of generic associated types development,
/// it was only accepted before the equals. To provide a transition period and
/// further evaluate this change, both are currently accepted. At some point in

View File

@ -1,5 +1,5 @@
warning: where clause not allowed here
--> $DIR/type-alias-where-fixable.rs:13:16
--> $DIR/where-clause-placement-assoc-type-in-impl.rs:13:16
|
LL | type Assoc where u32: Copy = ();
| ^^^^^^^^^^^^^^^
@ -13,7 +13,7 @@ LL + type Assoc = () where u32: Copy;
|
warning: where clause not allowed here
--> $DIR/type-alias-where-fixable.rs:16:17
--> $DIR/where-clause-placement-assoc-type-in-impl.rs:16:17
|
LL | type Assoc2 where u32: Copy = () where i32: Copy;
| ^^^^^^^^^^^^^^^
@ -26,7 +26,7 @@ LL + type Assoc2 = () where i32: Copy, u32: Copy;
|
warning: where clause not allowed here
--> $DIR/type-alias-where-fixable.rs:24:17
--> $DIR/where-clause-placement-assoc-type-in-impl.rs:24:17
|
LL | type Assoc2 where u32: Copy, i32: Copy = ();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -0,0 +1,15 @@
// check-pass
// run-rustfix
#![feature(associated_type_defaults)]
trait Trait {
// Not fine, suggests moving.
type Assoc = () where u32: Copy;
//~^ WARNING where clause not allowed here
// Not fine, suggests moving `u32: Copy`
type Assoc2 = () where i32: Copy, u32: Copy;
//~^ WARNING where clause not allowed here
}
fn main() {}

View File

@ -0,0 +1,15 @@
// check-pass
// run-rustfix
#![feature(associated_type_defaults)]
trait Trait {
// Not fine, suggests moving.
type Assoc where u32: Copy = ();
//~^ WARNING where clause not allowed here
// Not fine, suggests moving `u32: Copy`
type Assoc2 where u32: Copy = () where i32: Copy;
//~^ WARNING where clause not allowed here
}
fn main() {}

View File

@ -0,0 +1,29 @@
warning: where clause not allowed here
--> $DIR/where-clause-placement-assoc-type-in-trait.rs:8:16
|
LL | type Assoc where u32: Copy = ();
| ^^^^^^^^^^^^^^^
|
= note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
= note: `#[warn(deprecated_where_clause_location)]` on by default
help: move it to the end of the type declaration
|
LL - type Assoc where u32: Copy = ();
LL + type Assoc = () where u32: Copy;
|
warning: where clause not allowed here
--> $DIR/where-clause-placement-assoc-type-in-trait.rs:11:17
|
LL | type Assoc2 where u32: Copy = () where i32: Copy;
| ^^^^^^^^^^^^^^^
|
= note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
help: move it to the end of the type declaration
|
LL - type Assoc2 where u32: Copy = () where i32: Copy;
LL + type Assoc2 = () where i32: Copy, u32: Copy;
|
warning: 2 warnings emitted

View File

@ -1,5 +1,5 @@
error: where clauses are not allowed after the type for type aliases
--> $DIR/type-alias-where.rs:6:15
--> $DIR/where-clause-placement-type-alias.rs:6:15
|
LL | type Bar = () where u32: Copy;
| ^^^^^^^^^^^^^^^
@ -7,7 +7,7 @@ LL | type Bar = () where u32: Copy;
= note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
error: where clauses are not allowed after the type for type aliases
--> $DIR/type-alias-where.rs:8:15
--> $DIR/where-clause-placement-type-alias.rs:8:15
|
LL | type Baz = () where;
| ^^^^^