From d811a82da287cad9318d31881b91c4d8e3272d7f Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Sun, 3 Mar 2024 14:32:19 +0000 Subject: [PATCH 1/4] Update non-local-defns regarding parameterized traits and types --- .../3373-avoid-nonlocal-definitions-in-fns.md | 70 ++++++++++++++----- 1 file changed, 53 insertions(+), 17 deletions(-) diff --git a/text/3373-avoid-nonlocal-definitions-in-fns.md b/text/3373-avoid-nonlocal-definitions-in-fns.md index de7d76e76b8..9210a6b546f 100644 --- a/text/3373-avoid-nonlocal-definitions-in-fns.md +++ b/text/3373-avoid-nonlocal-definitions-in-fns.md @@ -20,7 +20,23 @@ to find potential definitions corresponding to uses within another function, or not cross-reference those definitions at all. Humans cross-referencing such uses and definitions may find themselves -similarly baffled. +similarly baffled by code such as the following: +```rust +trait Trait { + fn method(&self) {} +} + +struct Foo; + +fn _foo() { + struct Bar; + impl Trait for Foo {} +} + +fn main() { + Foo.method(); +} +``` This change helps humans limit the scope of their search and avoid looking for definitions inside other functions or items, without missing any relevant @@ -30,23 +46,40 @@ subsequent Rust edtion, tools will be able to rely on this as well. # Explanation [explanation]: #explanation -The following types of items, "expression-containing items", can contain -expressions, including the definitions of other items: +An "expression-containing item" is defined as any [expression] where an [item] +may be defined, for example: - Functions - Closures - The values assigned to `static` items or non-anonymous `const` items. - The discriminant values assigned to `enum` variants -Rust will emit a warn-by-default lint for all of the following cases: -- An item nested inside an expression-containing item (through any level of - nesting) may not define an `impl Type` block unless the `Type` is also nested - inside the same expression-containing item. -- An item nested inside an expression-containing item (through any level of - nesting) may not define an `impl Trait for Type` unless either the `Trait` or - the `Type` is also nested inside the same expression-containing item. -- An item nested inside an expression-containing item (through any level of - nesting) may not define an exported macro visible outside the - expression-containing item (e.g. using `#[macro_export]`). +As a special exception, anonymous `const` items are excluded from this +definition for the purpose of this RFC (see [unresolved-questions]). + +Rust will emit a warn-by-default lint when encountering an `impl` nested inside +an expression-containing item (through any level of nesting), unless any of the +following are true: +- For `impl T` or `impl TraitPath for T`, the definition of type `T` is also + nested inside the same expression-containing item. +- For `impl T` or `impl TraitPath for T`, the definition of + at least one of `T`, `X`, `Y`, .. is also nested inside the same expression- + containing item. +- For `impl Trait for TypePath` or `impl Trait for TypePath`, the + definition of `Trait` is also nested inside the same expression-containing + item. +- For `impl Trait for TypePath`, the definition of at least one of + `X`, `Y`, .. is also nested inside the same expression-containing item, *and* + the full path `Trait` may not be inferred from outside the + expression-containing item, and further that such inferences on `Trait` would + not be permitted even in the absense of all impls nested in expression- + containing items. + +For the purposes of the above rules, fundamental types such as `&X` and `&mut X` +are considered parameterized types (`T`). + +Rust will emit a warn-by-default lint when encountering an exported macro (e.g. +using `#[macro_export]`) nested inside an expression-containing item (through +any level of nesting). In a future edition, we may consider making this lint deny-by-default, or eventually making it a hard error. We'll evaluate the impact on the ecosystem @@ -74,11 +107,10 @@ the signature without reflecting those properties in the signature. # Unresolved questions [unresolved-questions]: #unresolved-questions -We'll need a crater run to look at how widespread this pattern is in existing -code. +Should we flag these definitions in anonymous `const` items as well? This is +used in some macro expansions for [compatibility reasons][1]. -Should we flag these definitions in anonymous `const` items as well, or would -that produce unwanted warnings? +Is the last rule regarding parameterized trait `impl` items viable to implement? # Future possibilities [future-possibilities]: #future-possibilities @@ -86,3 +118,7 @@ that produce unwanted warnings? If in the future Rust provides a "standalone `derive`" mechanism (e.g. `derive Trait for Type` as a standalone definition separate from `Type`), the `impl` produced by that mechanism would be subject to the same requirements. + +[expression]: https://doc.rust-lang.org/reference/expressions.html +[item]: https://doc.rust-lang.org/reference/items.html +[1]: https://github.com/rust-lang/rfcs/pull/3373#issuecomment-1885307786 From 0a29dda3ebfac52006540e301fbabe9f7854a84c Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Sun, 3 Mar 2024 14:59:00 +0000 Subject: [PATCH 2/4] Add new RFC --- text/3373-avoid-nonlocal-definitions-in-fns.md | 1 + 1 file changed, 1 insertion(+) diff --git a/text/3373-avoid-nonlocal-definitions-in-fns.md b/text/3373-avoid-nonlocal-definitions-in-fns.md index 9210a6b546f..93aa74a0321 100644 --- a/text/3373-avoid-nonlocal-definitions-in-fns.md +++ b/text/3373-avoid-nonlocal-definitions-in-fns.md @@ -1,6 +1,7 @@ - Feature Name: N/A - Start Date: 2022-01-19 - RFC PR: [rust-lang/rfcs#3373](https://github.com/rust-lang/rfcs/pull/3373) +- RFC PR #2: [rust-lang/rfcs#3581](https://github.com/rust-lang/rfcs/pull/3581) - Tracking Issue: [rust-lang/rust#120363](https://github.com/rust-lang/rust/issues/120363) # Summary From 426b048568cbf819da54d42e862341a23d18ec08 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Tue, 2 Apr 2024 10:27:51 +0100 Subject: [PATCH 3/4] Directly put URLs in links rather than using footnotes/endnotes --- text/3373-avoid-nonlocal-definitions-in-fns.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/text/3373-avoid-nonlocal-definitions-in-fns.md b/text/3373-avoid-nonlocal-definitions-in-fns.md index 93aa74a0321..af353136a7f 100644 --- a/text/3373-avoid-nonlocal-definitions-in-fns.md +++ b/text/3373-avoid-nonlocal-definitions-in-fns.md @@ -47,8 +47,10 @@ subsequent Rust edtion, tools will be able to rely on this as well. # Explanation [explanation]: #explanation -An "expression-containing item" is defined as any [expression] where an [item] -may be defined, for example: +An "expression-containing item" is defined as any +[expression](https://doc.rust-lang.org/reference/expressions.html) where an +[item](https://doc.rust-lang.org/reference/items.html) may be defined. For +example: - Functions - Closures - The values assigned to `static` items or non-anonymous `const` items. @@ -109,7 +111,8 @@ the signature without reflecting those properties in the signature. [unresolved-questions]: #unresolved-questions Should we flag these definitions in anonymous `const` items as well? This is -used in some macro expansions for [compatibility reasons][1]. +used in some macro expansions for +[compatibility reasons](https://github.com/rust-lang/rfcs/pull/3373#issuecomment-1885307786). Is the last rule regarding parameterized trait `impl` items viable to implement? @@ -119,7 +122,3 @@ Is the last rule regarding parameterized trait `impl` items viable to implement? If in the future Rust provides a "standalone `derive`" mechanism (e.g. `derive Trait for Type` as a standalone definition separate from `Type`), the `impl` produced by that mechanism would be subject to the same requirements. - -[expression]: https://doc.rust-lang.org/reference/expressions.html -[item]: https://doc.rust-lang.org/reference/items.html -[1]: https://github.com/rust-lang/rfcs/pull/3373#issuecomment-1885307786 From 29336a3cab97c7733e80015da35a7657a7343c8c Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Tue, 2 Apr 2024 10:32:08 +0100 Subject: [PATCH 4/4] Explain exception for anonymous const items --- text/3373-avoid-nonlocal-definitions-in-fns.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/text/3373-avoid-nonlocal-definitions-in-fns.md b/text/3373-avoid-nonlocal-definitions-in-fns.md index af353136a7f..278037f4b9d 100644 --- a/text/3373-avoid-nonlocal-definitions-in-fns.md +++ b/text/3373-avoid-nonlocal-definitions-in-fns.md @@ -56,8 +56,9 @@ example: - The values assigned to `static` items or non-anonymous `const` items. - The discriminant values assigned to `enum` variants -As a special exception, anonymous `const` items are excluded from this -definition for the purpose of this RFC (see [unresolved-questions]). +As an exception, anonymous `const` items are excluded from this +definition for the purposes of this RFC (see [unresolved-questions]), +as they're currently commonly used to define items within macros. Rust will emit a warn-by-default lint when encountering an `impl` nested inside an expression-containing item (through any level of nesting), unless any of the