Skip to content

Commit a317da4

Browse files
committed
Suggest the correct syntax for different struct types
1 parent 9bab0f0 commit a317da4

File tree

6 files changed

+62
-45
lines changed

6 files changed

+62
-45
lines changed

src/librustc_resolve/lib.rs

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2702,19 +2702,29 @@ impl<'a> Resolver<'a> {
27022702
}
27032703
return (err, candidates);
27042704
},
2705-
_ if ns == ValueNS && is_struct_like(def) => {
2706-
let mut accessible_ctor = true;
2707-
if let Def::Struct(def_id) = def {
2708-
if let Some((ctor_def, ctor_vis))
2709-
= this.struct_constructors.get(&def_id).cloned() {
2710-
accessible_ctor = this.is_accessible(ctor_vis);
2711-
if is_expected(ctor_def) && !accessible_ctor {
2712-
err.span_label(span, format!("constructor is not visible \
2713-
here due to private fields"));
2714-
}
2705+
(Def::Struct(def_id), _) if ns == ValueNS && is_struct_like(def) => {
2706+
if let Some((ctor_def, ctor_vis))
2707+
= this.struct_constructors.get(&def_id).cloned() {
2708+
let accessible_ctor = this.is_accessible(ctor_vis);
2709+
if is_expected(ctor_def) && !accessible_ctor {
2710+
err.span_label(span, format!("constructor is not visible \
2711+
here due to private fields"));
2712+
} else if accessible_ctor {
2713+
let block = match ctor_def {
2714+
Def::StructCtor(_, CtorKind::Fn) |
2715+
Def::VariantCtor(_, CtorKind::Fn) => "(/* fields */)",
2716+
Def::StructCtor(_, CtorKind::Fictive) |
2717+
Def::VariantCtor(_, CtorKind::Fictive) => {
2718+
" { /* fields */ }"
2719+
}
2720+
def => bug!("found def `{:?}` when looking for a ctor",
2721+
def),
2722+
};
2723+
err.span_label(span, format!("did you mean `{}{}`?",
2724+
path_str,
2725+
block));
27152726
}
2716-
}
2717-
if accessible_ctor {
2727+
} else {
27182728
err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?",
27192729
path_str));
27202730
}

src/test/ui/resolve/issue-18252.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0423]: expected function, found struct variant `Foo::Variant`
22
--> $DIR/issue-18252.rs:16:13
33
|
44
16 | let f = Foo::Variant(42);
5-
| ^^^^^^^^^^^^ did you mean `Foo::Variant { /* fields */ }`?
5+
| ^^^^^^^^^^^^ not a function
66

77
error: aborting due to previous error
88

src/test/ui/resolve/issue-19452.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ error[E0423]: expected value, found struct variant `Homura::Madoka`
22
--> $DIR/issue-19452.rs:19:18
33
|
44
19 | let homura = Homura::Madoka;
5-
| ^^^^^^^^^^^^^^ did you mean `Homura::Madoka { /* fields */ }`?
5+
| ^^^^^^^^^^^^^^ not a value
66

77
error[E0423]: expected value, found struct variant `issue_19452_aux::Homura::Madoka`
88
--> $DIR/issue-19452.rs:22:18
99
|
1010
22 | let homura = issue_19452_aux::Homura::Madoka;
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ did you mean `issue_19452_aux::Homura::Madoka { /* fields */ }`?
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a value
1212

1313
error: aborting due to 2 previous errors
1414

src/test/ui/resolve/privacy-struct-ctor.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ extern crate privacy_struct_ctor as xcrate;
1414

1515
mod m {
1616
pub struct S(u8);
17+
pub struct S2 {
18+
s: u8
19+
}
1720

1821
pub mod n {
1922
pub(in m) struct Z(pub(in m::n) u8);
@@ -29,13 +32,17 @@ mod m {
2932
}
3033

3134
use m::S; // OK, only the type is imported
35+
use m::S2; // OK, only the type is imported
3236

3337
fn main() {
3438
m::S; //~ ERROR tuple struct `S` is private
3539
S;
3640
//~^ ERROR expected value, found struct `S`
3741
m::n::Z; //~ ERROR tuple struct `Z` is private
3842

43+
S2;
44+
//~^ ERROR expected value, found struct `S2`
45+
3946
xcrate::m::S; //~ ERROR tuple struct `S` is private
4047
xcrate::S;
4148
//~^ ERROR expected value, found struct `xcrate::S`
Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,71 @@
11
error[E0423]: expected value, found struct `Z`
2-
--> $DIR/privacy-struct-ctor.rs:26:9
2+
--> $DIR/privacy-struct-ctor.rs:29:9
33
|
4-
26 | Z;
4+
29 | Z;
55
| ^
66
| |
77
| did you mean `S`?
88
| constructor is not visible here due to private fields
99
help: possible better candidate is found in another module, you can import it into scope
1010
|
11-
22 | use m::n::Z;
11+
25 | use m::n::Z;
1212
|
1313

1414
error[E0423]: expected value, found struct `S`
15-
--> $DIR/privacy-struct-ctor.rs:35:5
15+
--> $DIR/privacy-struct-ctor.rs:39:5
1616
|
17-
35 | S;
17+
39 | S;
1818
| ^ constructor is not visible here due to private fields
1919
help: possible better candidate is found in another module, you can import it into scope
2020
|
21-
31 | use m::S;
21+
34 | use m::S;
22+
|
23+
24+
error[E0423]: expected value, found struct `S2`
25+
--> $DIR/privacy-struct-ctor.rs:43:5
2226
|
27+
43 | S2;
28+
| ^^ did you mean `S2 { /* fields */ }`?
2329

2430
error[E0423]: expected value, found struct `xcrate::S`
25-
--> $DIR/privacy-struct-ctor.rs:40:5
31+
--> $DIR/privacy-struct-ctor.rs:47:5
2632
|
27-
40 | xcrate::S;
33+
47 | xcrate::S;
2834
| ^^^^^^^^^ constructor is not visible here due to private fields
2935
help: possible better candidate is found in another module, you can import it into scope
3036
|
31-
31 | use m::S;
37+
34 | use m::S;
3238
|
3339

3440
error[E0603]: tuple struct `Z` is private
35-
--> $DIR/privacy-struct-ctor.rs:25:9
41+
--> $DIR/privacy-struct-ctor.rs:28:9
3642
|
37-
25 | n::Z; //~ ERROR tuple struct `Z` is private
43+
28 | n::Z; //~ ERROR tuple struct `Z` is private
3844
| ^^^^
3945

4046
error[E0603]: tuple struct `S` is private
41-
--> $DIR/privacy-struct-ctor.rs:34:5
47+
--> $DIR/privacy-struct-ctor.rs:38:5
4248
|
43-
34 | m::S; //~ ERROR tuple struct `S` is private
49+
38 | m::S; //~ ERROR tuple struct `S` is private
4450
| ^^^^
4551

4652
error[E0603]: tuple struct `Z` is private
47-
--> $DIR/privacy-struct-ctor.rs:37:5
53+
--> $DIR/privacy-struct-ctor.rs:41:5
4854
|
49-
37 | m::n::Z; //~ ERROR tuple struct `Z` is private
55+
41 | m::n::Z; //~ ERROR tuple struct `Z` is private
5056
| ^^^^^^^
5157

5258
error[E0603]: tuple struct `S` is private
53-
--> $DIR/privacy-struct-ctor.rs:39:5
59+
--> $DIR/privacy-struct-ctor.rs:46:5
5460
|
55-
39 | xcrate::m::S; //~ ERROR tuple struct `S` is private
61+
46 | xcrate::m::S; //~ ERROR tuple struct `S` is private
5662
| ^^^^^^^^^^^^
5763

5864
error[E0603]: tuple struct `Z` is private
59-
--> $DIR/privacy-struct-ctor.rs:42:5
65+
--> $DIR/privacy-struct-ctor.rs:49:5
6066
|
61-
42 | xcrate::m::n::Z; //~ ERROR tuple struct `Z` is private
67+
49 | xcrate::m::n::Z; //~ ERROR tuple struct `Z` is private
6268
| ^^^^^^^^^^^^^^^
6369

64-
error: aborting due to 8 previous errors
70+
error: aborting due to 9 previous errors
6571

src/test/ui/resolve/tuple-struct-alias.stderr

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,25 @@ error[E0423]: expected function, found self type `Self`
22
--> $DIR/tuple-struct-alias.rs:16:17
33
|
44
16 | let s = Self(0, 1); //~ ERROR expected function
5-
| ^^^^ did you mean `Self { /* fields */ }`?
5+
| ^^^^ not a function
66

77
error[E0532]: expected tuple struct/variant, found self type `Self`
88
--> $DIR/tuple-struct-alias.rs:18:13
99
|
1010
18 | Self(..) => {} //~ ERROR expected tuple struct/variant
11-
| ^^^^ did you mean `Self { /* fields */ }`?
11+
| ^^^^ not a tuple struct/variant
1212

1313
error[E0423]: expected function, found type alias `A`
1414
--> $DIR/tuple-struct-alias.rs:24:13
1515
|
1616
24 | let s = A(0, 1); //~ ERROR expected function
17-
| ^
18-
| |
19-
| did you mean `S`?
20-
| did you mean `A { /* fields */ }`?
17+
| ^ did you mean `S`?
2118

2219
error[E0532]: expected tuple struct/variant, found type alias `A`
2320
--> $DIR/tuple-struct-alias.rs:26:9
2421
|
2522
26 | A(..) => {} //~ ERROR expected tuple struct/variant
26-
| ^
27-
| |
28-
| did you mean `S`?
29-
| did you mean `A { /* fields */ }`?
23+
| ^ did you mean `S`?
3024

3125
error: aborting due to 4 previous errors
3226

0 commit comments

Comments
 (0)