Enum variants completely shadow inherent associated functions.
Consider the code below:
enum Foo { Bar(i32) }
impl Foo {
fn Bar(x: i32) -> Foo {
println!("I'm uncallable");
Foo::Bar(x)
}
}
fn main() {
Foo::Bar(0); // Variant constructor.
<Foo>::Bar(0); // Inherent function.
}
It compiles successfully and terminates with no output. There is an ambiguity between the variant and the associated function, <strike>though it seems we always prefer the variant, making the associated function uncallable</strike>. Having an inherent associated function with the same name as a variant should be an error.
Edit: @petrochenkov points out that it's not actually uncallable, you can call it with <Foo>::Bar(0). A deny-by-default lint then perhaps?
I agree this a breaking change worth having.
It compiles successfully
It compiles, but it gives a clear warning and it's often a bad idea to ignore rustc warnings:
warning: method `Bar` should have a snake case name such as `bar` --> ...\test.rs:4:5 | 4 | / fn Bar(x: i32) -> Foo { 5 | | println!("I'm uncallable"); 6 | | Foo::Bar(x) 7 | | } | |_____^ | = note: #[warn(non_snake_case)] on by defaultleonardo-m at 2018-03-05 22:41:21
This is a duplicate of some old issue, the decision was to always prioritize variants over other associated items, thus breaking the currently working way to call the "uncallable"
Bar-<Foo>::Bar.Vadim Petrochenkov at 2018-03-05 22:49:50
There was also a suggestion to make this an overlap error instead of leaving the associated fn
Barlegal but uncallable.Vadim Petrochenkov at 2018-03-05 22:52:00
This issue is a part of https://github.com/rust-lang/rust/issues/26264 / https://github.com/rust-lang/rfcs/pull/2338 really.
Vadim Petrochenkov at 2018-03-05 22:52:26
#28320 is the closest I could find.
Leonardo Yvens at 2018-03-05 22:52:55
@petrochenkov should we lint on the shadowing at least? Should we add some way of referring to the method at all?
Esteban Kuber at 2019-05-23 00:21:25
Variants are inherent associated items now, so this should be reported as an overlap error, similarly to
struct S; impl S { fn foo() {} } impl S { fn foo() {} }Vadim Petrochenkov at 2019-05-23 09:08:08
@petrochenkov It doesn't seem to generate an overlap error currently?
Mazdak Farrokhzad at 2019-06-09 06:22:36
No, the overlap error is not reported currently, someone needs to implement it.
Vadim Petrochenkov at 2019-06-09 07:31:20
Triage: still compiles with no output. Which seems strange to me, given that
<Foo>::Bar(0)is supposed to be able to call it?Steve Klabnik at 2021-04-20 18:24:09
From 1.0 to 1.33 (inclusive)
<details><summary>full test</summary><Foo>::Bar(0)worked to call the inherent method, 1.34 to 1.36 failed to compile witherror: enum variants on type aliases are experimental, 1.37+ compile and resolve to the enum variant in both cases.> for v in 1.{0..7}.0 1.{8..53}; do rustc +$v --version && rustc +$v main.rs --allow=warnings && ./main; done rustc 1.0.0 (a59de37e9 2015-05-13) (built 2015-05-14) I'm uncallable rustc 1.1.0 (35ceea399 2015-06-19) I'm uncallable rustc 1.2.0 (082e47636 2015-08-03) I'm uncallable rustc 1.3.0 (9a92aaf19 2015-09-15) I'm uncallable rustc 1.4.0 (8ab8581f6 2015-10-27) I'm uncallable rustc 1.5.0 (3d7cd77e4 2015-12-04) I'm uncallable rustc 1.6.0 (c30b771ad 2016-01-19) I'm uncallable rustc 1.7.0 (a5d1e7a59 2016-02-29) I'm uncallable rustc 1.8.0 (db2939409 2016-04-11) I'm uncallable rustc 1.9.0 (e4e8b6668 2016-05-18) I'm uncallable rustc 1.10.0 (cfcb716cf 2016-07-03) I'm uncallable rustc 1.11.0 (9b21dcd6a 2016-08-15) I'm uncallable rustc 1.12.1 (d4f39402a 2016-10-19) I'm uncallable rustc 1.13.0 (2c6933acc 2016-11-07) I'm uncallable rustc 1.14.0 (e8a012324 2016-12-16) I'm uncallable rustc 1.15.1 (021bd294c 2017-02-08) I'm uncallable rustc 1.16.0 (30cf806ef 2017-03-10) I'm uncallable rustc 1.17.0 (56124baa9 2017-04-24) I'm uncallable rustc 1.18.0 (03fc9d622 2017-06-06) I'm uncallable rustc 1.19.0 (0ade33941 2017-07-17) I'm uncallable rustc 1.20.0 (f3d6973f4 2017-08-27) I'm uncallable rustc 1.21.0 (3b72af97e 2017-10-09) I'm uncallable rustc 1.22.1 (05e2e1c41 2017-11-22) I'm uncallable rustc 1.23.0 (766bd11c8 2018-01-01) I'm uncallable rustc 1.24.1 (d3ae9a9e0 2018-02-27) I'm uncallable rustc 1.25.0 (84203cac6 2018-03-25) I'm uncallable rustc 1.26.2 (594fb253c 2018-06-01) I'm uncallable rustc 1.27.2 (58cc626de 2018-07-18) I'm uncallable rustc 1.28.0 (9634041f0 2018-07-30) I'm uncallable rustc 1.29.2 (17a9dc751 2018-10-05) I'm uncallable rustc 1.30.1 (1433507eb 2018-11-07) I'm uncallable rustc 1.31.1 (b6c32da9b 2018-12-18) I'm uncallable rustc 1.32.0 (9fda7c223 2019-01-16) I'm uncallable rustc 1.33.0 (2aa4c46cf 2019-02-28) I'm uncallable rustc 1.34.2 (6c2484dc3 2019-05-13) error: enum variants on type aliases are experimental --> main.rs:12:5 | 12 | <Foo>::Bar(0); // Inherent function. | ^^^^^^^^^^ error: aborting due to previous error rustc 1.35.0 (3c235d560 2019-05-20) error: enum variants on type aliases are experimental --> main.rs:12:5 | 12 | <Foo>::Bar(0); // Inherent function. | ^^^^^^^^^^ error: aborting due to previous error rustc 1.36.0 (a53f9df32 2019-07-03) error: enum variants on type aliases are experimental --> main.rs:12:5 | 12 | <Foo>::Bar(0); // Inherent function. | ^^^^^^^^^^ error: aborting due to previous error rustc 1.37.0 (eae3437df 2019-08-13) rustc 1.38.0 (625451e37 2019-09-23) rustc 1.39.0 (4560ea788 2019-11-04) rustc 1.40.0 (73528e339 2019-12-16) rustc 1.41.1 (f3e1a954d 2020-02-24) rustc 1.42.0 (b8cedc004 2020-03-09) rustc 1.43.1 (8d69840ab 2020-05-04) rustc 1.44.1 (c7087fe00 2020-06-17) rustc 1.45.2 (d3fb005a3 2020-07-31) rustc 1.46.0 (04488afe3 2020-08-24) rustc 1.47.0 (18bf6b4f0 2020-10-07) rustc 1.48.0 (7eac88abb 2020-11-16) rustc 1.49.0 (e1884a8e3 2020-12-29) rustc 1.50.0 (cb75ad5db 2021-02-10) rustc 1.51.0 (2fd73fabe 2021-03-23) rustc 1.52.1 (9bc8c42bb 2021-05-09) rustc 1.53.0 (53cb7b09b 2021-06-17)Nemo157 at 2021-06-21 18:37:47
https://github.com/rust-lang/rust/issues/48758#issuecomment-495133781 describes the current status, the overlap error is still not implemented.
Vadim Petrochenkov at 2024-08-01 15:53:14