Skip to content

Commit 2ce2d14

Browse files
committed
Account for union
1 parent 08d31e0 commit 2ce2d14

File tree

4 files changed

+50
-5
lines changed

4 files changed

+50
-5
lines changed

compiler/rustc_infer/src/infer/error_reporting/mod.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1842,13 +1842,20 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
18421842
{
18431843
if let ObligationCauseCode::Pattern { span: Some(span), .. } = cause.code {
18441844
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
1845+
let suggestion = if expected_def.is_struct() {
1846+
format!("{}.{}", snippet, name)
1847+
} else if expected_def.is_union() {
1848+
format!("unsafe {{ {}.{} }}", snippet, name)
1849+
} else {
1850+
return;
1851+
};
18451852
diag.span_suggestion(
18461853
span,
18471854
&format!(
18481855
"you might have meant to use field `{}` of type `{}`",
18491856
name, ty
18501857
),
1851-
format!("{}.{}", snippet, name),
1858+
suggestion,
18521859
Applicability::MaybeIncorrect,
18531860
);
18541861
}

src/test/ui/suggestions/field-access.fixed

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ enum B {
1010
Snd,
1111
}
1212

13+
union Foo {
14+
bar: u32,
15+
qux: f32,
16+
}
17+
1318
fn main() {
1419
let a = A { b: B::Fst };
1520
if let B::Fst = a.b {}; //~ ERROR mismatched types [E0308]
@@ -20,4 +25,11 @@ fn main() {
2025
B::Fst => (), //~ ERROR mismatched types [E0308]
2126
B::Snd => (), //~ ERROR mismatched types [E0308]
2227
}
28+
29+
let foo = Foo { bar: 42 };
30+
match unsafe { foo.bar } {
31+
//~^ HELP you might have meant to use field `bar` of type `u32`
32+
1u32 => (), //~ ERROR mismatched types [E0308]
33+
_ => (),
34+
}
2335
}

src/test/ui/suggestions/field-access.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ enum B {
1010
Snd,
1111
}
1212

13+
union Foo {
14+
bar: u32,
15+
qux: f32,
16+
}
17+
1318
fn main() {
1419
let a = A { b: B::Fst };
1520
if let B::Fst = a {}; //~ ERROR mismatched types [E0308]
@@ -20,4 +25,11 @@ fn main() {
2025
B::Fst => (), //~ ERROR mismatched types [E0308]
2126
B::Snd => (), //~ ERROR mismatched types [E0308]
2227
}
28+
29+
let foo = Foo { bar: 42 };
30+
match foo {
31+
//~^ HELP you might have meant to use field `bar` of type `u32`
32+
1u32 => (), //~ ERROR mismatched types [E0308]
33+
_ => (),
34+
}
2335
}

src/test/ui/suggestions/field-access.stderr

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0308]: mismatched types
2-
--> $DIR/field-access.rs:15:12
2+
--> $DIR/field-access.rs:20:12
33
|
44
LL | Fst,
55
| --- unit variant defined here
@@ -15,7 +15,7 @@ LL | if let B::Fst = a.b {};
1515
| ^^^
1616

1717
error[E0308]: mismatched types
18-
--> $DIR/field-access.rs:20:9
18+
--> $DIR/field-access.rs:25:9
1919
|
2020
LL | Fst,
2121
| --- unit variant defined here
@@ -32,7 +32,7 @@ LL | match a.b {
3232
| ^^^
3333

3434
error[E0308]: mismatched types
35-
--> $DIR/field-access.rs:21:9
35+
--> $DIR/field-access.rs:26:9
3636
|
3737
LL | Snd,
3838
| --- unit variant defined here
@@ -48,6 +48,20 @@ help: you might have meant to use field `b` of type `B`
4848
LL | match a.b {
4949
| ^^^
5050

51-
error: aborting due to 3 previous errors
51+
error[E0308]: mismatched types
52+
--> $DIR/field-access.rs:32:9
53+
|
54+
LL | match foo {
55+
| --- this expression has type `Foo`
56+
LL |
57+
LL | 1u32 => (),
58+
| ^^^^ expected union `Foo`, found `u32`
59+
|
60+
help: you might have meant to use field `bar` of type `u32`
61+
|
62+
LL | match unsafe { foo.bar } {
63+
| ^^^^^^^^^^^^^^^^^^
64+
65+
error: aborting due to 4 previous errors
5266

5367
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)