Skip to content

Commit 748effd

Browse files
authored
Rollup merge of #135222 - estebank:issue-135209, r=compiler-errors
Ensure that we don't try to access fields on a non-struct pattern type Fix #135209.
2 parents b87a004 + 592f2c9 commit 748effd

5 files changed

+67
-4
lines changed

Diff for: compiler/rustc_resolve/src/late/diagnostics.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1130,7 +1130,9 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
11301130
let None = following_seg else { return };
11311131
for rib in self.ribs[ValueNS].iter().rev() {
11321132
for (def_id, spans) in &rib.patterns_with_skipped_bindings {
1133-
if let Some(fields) = self.r.field_idents(*def_id) {
1133+
if let DefKind::Struct | DefKind::Variant = self.r.tcx.def_kind(*def_id)
1134+
&& let Some(fields) = self.r.field_idents(*def_id)
1135+
{
11341136
for field in fields {
11351137
if field.name == segment.ident.name {
11361138
if spans.iter().all(|(_, had_error)| had_error.is_err()) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Regression test for #135209.
2+
// We ensure that we don't try to access fields on a non-struct pattern type.
3+
fn main() {
4+
if let <Vec<()> as Iterator>::Item { .. } = 1 {
5+
//~^ ERROR E0658
6+
//~| ERROR E0071
7+
//~| ERROR E0277
8+
x //~ ERROR E0425
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
error[E0425]: cannot find value `x` in this scope
2+
--> $DIR/struct-pattern-on-non-struct-resolve-error.rs:8:9
3+
|
4+
LL | x
5+
| ^ not found in this scope
6+
7+
error[E0658]: usage of qualified paths in this context is experimental
8+
--> $DIR/struct-pattern-on-non-struct-resolve-error.rs:4:12
9+
|
10+
LL | if let <Vec<()> as Iterator>::Item { .. } = 1 {
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
|
13+
= note: see issue #86935 <https://github.com/rust-lang/rust/issues/86935> for more information
14+
= help: add `#![feature(more_qualified_paths)]` to the crate attributes to enable
15+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
16+
17+
error[E0071]: expected struct, variant or union type, found inferred type
18+
--> $DIR/struct-pattern-on-non-struct-resolve-error.rs:4:12
19+
|
20+
LL | if let <Vec<()> as Iterator>::Item { .. } = 1 {
21+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a struct
22+
23+
error[E0277]: `Vec<()>` is not an iterator
24+
--> $DIR/struct-pattern-on-non-struct-resolve-error.rs:4:12
25+
|
26+
LL | if let <Vec<()> as Iterator>::Item { .. } = 1 {
27+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Vec<()>` is not an iterator
28+
|
29+
= help: the trait `Iterator` is not implemented for `Vec<()>`
30+
31+
error: aborting due to 4 previous errors
32+
33+
Some errors have detailed explanations: E0071, E0277, E0425, E0658.
34+
For more information about an error, try `rustc --explain E0071`.

Diff for: tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.rs

+9
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ struct Website {
33
title: Option<String>,
44
}
55

6+
enum Foo {
7+
Bar { a: i32 },
8+
}
9+
610
fn main() {
711
let website = Website {
812
url: "http://www.example.com".into(),
@@ -18,4 +22,9 @@ fn main() {
1822
println!("[{}]({})", title, url); //~ ERROR cannot find value `title` in this scope
1923
//~^ NOTE not found in this scope
2024
}
25+
26+
let x = Foo::Bar { a: 1 };
27+
if let Foo::Bar { .. } = x { //~ NOTE this pattern
28+
println!("{a}"); //~ ERROR cannot find value `a` in this scope
29+
}
2130
}
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
11
error: expected `,`
2-
--> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:12:31
2+
--> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:16:31
33
|
44
LL | if let Website { url, Some(title) } = website {
55
| ------- ^
66
| |
77
| while parsing the fields for this pattern
88

99
error[E0425]: cannot find value `title` in this scope
10-
--> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:18:30
10+
--> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:22:30
1111
|
1212
LL | if let Website { url, .. } = website {
1313
| ------------------- this pattern doesn't include `title`, which is available in `Website`
1414
LL | println!("[{}]({})", title, url);
1515
| ^^^^^ not found in this scope
1616

17-
error: aborting due to 2 previous errors
17+
error[E0425]: cannot find value `a` in this scope
18+
--> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:28:20
19+
|
20+
LL | if let Foo::Bar { .. } = x {
21+
| --------------- this pattern doesn't include `a`, which is available in `Bar`
22+
LL | println!("{a}");
23+
| ^ help: a local variable with a similar name exists: `x`
24+
25+
error: aborting due to 3 previous errors
1826

1927
For more information about this error, try `rustc --explain E0425`.

0 commit comments

Comments
 (0)