Account for union

This commit is contained in:
Hirochika Matsumoto 2021-01-30 14:18:50 +09:00
parent 08d31e0f09
commit 2ce2d145c2
4 changed files with 50 additions and 5 deletions

View file

@ -1842,13 +1842,20 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
{ {
if let ObligationCauseCode::Pattern { span: Some(span), .. } = cause.code { if let ObligationCauseCode::Pattern { span: Some(span), .. } = cause.code {
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
let suggestion = if expected_def.is_struct() {
format!("{}.{}", snippet, name)
} else if expected_def.is_union() {
format!("unsafe {{ {}.{} }}", snippet, name)
} else {
return;
};
diag.span_suggestion( diag.span_suggestion(
span, span,
&format!( &format!(
"you might have meant to use field `{}` of type `{}`", "you might have meant to use field `{}` of type `{}`",
name, ty name, ty
), ),
format!("{}.{}", snippet, name), suggestion,
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
); );
} }

View file

@ -10,6 +10,11 @@ enum B {
Snd, Snd,
} }
union Foo {
bar: u32,
qux: f32,
}
fn main() { fn main() {
let a = A { b: B::Fst }; let a = A { b: B::Fst };
if let B::Fst = a.b {}; //~ ERROR mismatched types [E0308] if let B::Fst = a.b {}; //~ ERROR mismatched types [E0308]
@ -20,4 +25,11 @@ fn main() {
B::Fst => (), //~ ERROR mismatched types [E0308] B::Fst => (), //~ ERROR mismatched types [E0308]
B::Snd => (), //~ ERROR mismatched types [E0308] B::Snd => (), //~ ERROR mismatched types [E0308]
} }
let foo = Foo { bar: 42 };
match unsafe { foo.bar } {
//~^ HELP you might have meant to use field `bar` of type `u32`
1u32 => (), //~ ERROR mismatched types [E0308]
_ => (),
}
} }

View file

@ -10,6 +10,11 @@ enum B {
Snd, Snd,
} }
union Foo {
bar: u32,
qux: f32,
}
fn main() { fn main() {
let a = A { b: B::Fst }; let a = A { b: B::Fst };
if let B::Fst = a {}; //~ ERROR mismatched types [E0308] if let B::Fst = a {}; //~ ERROR mismatched types [E0308]
@ -20,4 +25,11 @@ fn main() {
B::Fst => (), //~ ERROR mismatched types [E0308] B::Fst => (), //~ ERROR mismatched types [E0308]
B::Snd => (), //~ ERROR mismatched types [E0308] B::Snd => (), //~ ERROR mismatched types [E0308]
} }
let foo = Foo { bar: 42 };
match foo {
//~^ HELP you might have meant to use field `bar` of type `u32`
1u32 => (), //~ ERROR mismatched types [E0308]
_ => (),
}
} }

View file

@ -1,5 +1,5 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/field-access.rs:15:12 --> $DIR/field-access.rs:20:12
| |
LL | Fst, LL | Fst,
| --- unit variant defined here | --- unit variant defined here
@ -15,7 +15,7 @@ LL | if let B::Fst = a.b {};
| ^^^ | ^^^
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/field-access.rs:20:9 --> $DIR/field-access.rs:25:9
| |
LL | Fst, LL | Fst,
| --- unit variant defined here | --- unit variant defined here
@ -32,7 +32,7 @@ LL | match a.b {
| ^^^ | ^^^
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/field-access.rs:21:9 --> $DIR/field-access.rs:26:9
| |
LL | Snd, LL | Snd,
| --- unit variant defined here | --- unit variant defined here
@ -48,6 +48,20 @@ help: you might have meant to use field `b` of type `B`
LL | match a.b { LL | match a.b {
| ^^^ | ^^^
error: aborting due to 3 previous errors error[E0308]: mismatched types
--> $DIR/field-access.rs:32:9
|
LL | match foo {
| --- this expression has type `Foo`
LL |
LL | 1u32 => (),
| ^^^^ expected union `Foo`, found `u32`
|
help: you might have meant to use field `bar` of type `u32`
|
LL | match unsafe { foo.bar } {
| ^^^^^^^^^^^^^^^^^^
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0308`. For more information about this error, try `rustc --explain E0308`.