Skip to content

Commit e9ec442

Browse files
authored
Rollup merge of #122910 - compiler-errors:unit-struct-in-path-pat-only, r=petrochenkov
Validate that we're only matching on unit struct for path pattern Resolution doesn't validate that we only really take `CtorKind::Unit` in path patterns, since all it sees is `Res::SelfCtor(def_id)`. Check this instead during pattern typeck. r? petrochenkov Fixes #122809
2 parents ccc5310 + 08235b1 commit e9ec442

6 files changed

+91
-8
lines changed

compiler/rustc_hir_typeck/src/pat.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -919,8 +919,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
919919
let e = report_unexpected_variant_res(tcx, res, qpath, pat.span, E0533, expected);
920920
return Ty::new_error(tcx, e);
921921
}
922-
Res::SelfCtor(..)
923-
| Res::Def(
922+
Res::SelfCtor(def_id) => {
923+
if let ty::Adt(adt_def, _) = *tcx.type_of(def_id).skip_binder().kind()
924+
&& adt_def.is_struct()
925+
&& let Some((CtorKind::Const, _)) = adt_def.non_enum_variant().ctor
926+
{
927+
// Ok, we allow unit struct ctors in patterns only.
928+
} else {
929+
let e = report_unexpected_variant_res(
930+
tcx,
931+
res,
932+
qpath,
933+
pat.span,
934+
E0533,
935+
"unit struct",
936+
);
937+
return Ty::new_error(tcx, e);
938+
}
939+
}
940+
Res::Def(
924941
DefKind::Ctor(_, CtorKind::Const)
925942
| DefKind::Const
926943
| DefKind::AssocConst

tests/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ impl S {
44
fn foo(&mur Self) {}
55
//~^ ERROR expected identifier, found keyword `Self`
66
//~| ERROR expected one of `:`, `@`
7-
//~| ERROR the `Self` constructor can only be used with
7+
//~| ERROR expected unit struct, found self constructor `Self`
88
fn bar(&'static mur Self) {}
99
//~^ ERROR unexpected lifetime
1010
//~| ERROR expected identifier, found keyword `Self`
1111
//~| ERROR expected one of `:`, `@`
12-
//~| ERROR the `Self` constructor can only be used with
12+
//~| ERROR expected unit struct, found self constructor `Self`
1313

1414
fn baz(&mur Self @ _) {}
1515
//~^ ERROR expected one of `:`, `@`

tests/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.stderr

+5-4
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,18 @@ error: expected one of `:`, `@`, or `|`, found keyword `Self`
4040
LL | fn baz(&mur Self @ _) {}
4141
| ^^^^ expected one of `:`, `@`, or `|`
4242

43-
error: the `Self` constructor can only be used with tuple or unit structs
43+
error[E0533]: expected unit struct, found self constructor `Self`
4444
--> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:4:17
4545
|
4646
LL | fn foo(&mur Self) {}
47-
| ^^^^ help: use curly brackets: `Self { /* fields */ }`
47+
| ^^^^ not a unit struct
4848

49-
error: the `Self` constructor can only be used with tuple or unit structs
49+
error[E0533]: expected unit struct, found self constructor `Self`
5050
--> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:8:25
5151
|
5252
LL | fn bar(&'static mur Self) {}
53-
| ^^^^ help: use curly brackets: `Self { /* fields */ }`
53+
| ^^^^ not a unit struct
5454

5555
error: aborting due to 8 previous errors
5656

57+
For more information about this error, try `rustc --explain E0533`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//@ revisions: tuple unit struct_
2+
//@[unit] check-pass
3+
4+
#[cfg(unit)]
5+
mod unit {
6+
struct S;
7+
impl S {
8+
fn foo() {
9+
let Self = S;
10+
}
11+
}
12+
}
13+
14+
#[cfg(tuple)]
15+
mod tuple {
16+
struct S(());
17+
impl S {
18+
fn foo() {
19+
let Self = S;
20+
//[tuple]~^ ERROR expected unit struct
21+
}
22+
}
23+
}
24+
25+
#[cfg(struct_)]
26+
mod struct_ {
27+
struct S {}
28+
impl S {
29+
fn foo() {
30+
let Self = S;
31+
//[struct_]~^ ERROR expected value, found struct `S`
32+
//[struct_]~| ERROR expected unit struct, found self constructor `Self`
33+
}
34+
}
35+
}
36+
37+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error[E0423]: expected value, found struct `S`
2+
--> $DIR/no-match-tuple-variant-self-ctor.rs:30:24
3+
|
4+
LL | struct S {}
5+
| ----------- `S` defined here
6+
...
7+
LL | let Self = S;
8+
| ^ help: use struct literal syntax instead: `S {}`
9+
10+
error[E0533]: expected unit struct, found self constructor `Self`
11+
--> $DIR/no-match-tuple-variant-self-ctor.rs:30:17
12+
|
13+
LL | let Self = S;
14+
| ^^^^ not a unit struct
15+
16+
error: aborting due to 2 previous errors
17+
18+
Some errors have detailed explanations: E0423, E0533.
19+
For more information about an error, try `rustc --explain E0423`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0533]: expected unit struct, found self constructor `Self`
2+
--> $DIR/no-match-tuple-variant-self-ctor.rs:19:17
3+
|
4+
LL | let Self = S;
5+
| ^^^^ not a unit struct
6+
7+
error: aborting due to 1 previous error
8+
9+
For more information about this error, try `rustc --explain E0533`.

0 commit comments

Comments
 (0)